程序化 UIView 内的程序化 UIButton 不起作用

Posted

技术标签:

【中文标题】程序化 UIView 内的程序化 UIButton 不起作用【英文标题】:Programmatic UIButton inside programmatic UIView not working 【发布时间】:2018-01-19 21:49:58 【问题描述】:

我创建了一个程序化 UIView 来显示具有模式外观的文本。我已经全部完成并且对结果很满意,但是当我按下 UIButton“X”时,什么也没有发生。

我已经阅读了很多关于 *** 的 UIButton 问题,但似乎没有一个对我有帮助。

代码如下:

class ViewDialogViewController: UIViewController 

var myMutableString = NSMutableAttributedString()

var myLabel = UITextView()

fileprivate var dialogViewWidth: CGFloat = UIScreen.main.bounds.width
fileprivate var dialogViewHeight: CGFloat = UIScreen.main.bounds.height

fileprivate var blackView = UIView()
fileprivate var titleView = UIView()
var titleLabel = UILabel()

fileprivate var okButton: UIButton!
fileprivate var dialogView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
fileprivate let stackView = UIStackView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))

var titleDialog: String = ""

override func viewDidLoad() 
    super.viewDidLoad()

    self.splitViewController?.preferredDisplayMode = UISplitViewControllerDisplayMode.primaryOverlay

    blackView = UIView(frame: CGRect(x: 0, y: 0, width: dialogViewWidth, height: dialogViewHeight))
    blackView.backgroundColor = UIColor.black.withAlphaComponent(0.6)
    self.view.addSubview(blackView)

    createDialogView()
    createTitleLabel()
    createOkButton()

    let myFont = UIFont (name: "Arial", size: 16.0)
    let myAttributes = [
        NSAttributedStringKey.font : myFont!
    ]

    let paragraphStyleCenter = NSMutableParagraphStyle()
    paragraphStyleCenter.alignment = NSTextAlignment.center

    let paragraphStyleBullet = NSMutableParagraphStyle()
    paragraphStyleBullet.headIndent = 9


    let paragraphStyleIndent = NSMutableParagraphStyle()
    paragraphStyleIndent.firstLineHeadIndent = 9

    let paragraphStyleSpacing = NSMutableParagraphStyle()
    paragraphStyleSpacing.lineSpacing = 1.2

    myLabel =  UITextView(frame: CGRect(x: 15, y: 50, width: (dialogViewWidth * 0.8) - 30, height: (dialogViewHeight * 0.8) - 55))

    self.myMutableString = NSMutableAttributedString (string: sharksText, attributes: myAttributes)

    myMutableString.addAttribute(NSAttributedStringKey.font, value: UIFont.italicSystemFont(ofSize: 16.0), range: ( NSRange (location: 2, length: 32)))
    myMutableString.addAttribute(NSAttributedStringKey.font, value: UIFont.boldSystemFont(ofSize: 16.0), range: ( NSRange (location: 35, length: 21)))
    myMutableString.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.blue, range: ( NSRange (location: 35, length: 21)))
    myMutableString.addAttribute(NSAttributedStringKey.font, value: UIFont.boldSystemFont(ofSize: 19.0), range: ( NSRange (location: 57, length: 21)))
    myMutableString.addAttribute(NSAttributedStringKey.paragraphStyle, value: paragraphStyleCenter, range: NSRange (location: 57, length: 21))
    myMutableString.addAttribute(NSAttributedStringKey.paragraphStyle, value: paragraphStyleBullet, range: NSRange (location: 2084, length: 3120))

    myLabel.attributedText = myMutableString


    self.dialogView.addSubview(myLabel)



@objc func okButtonAction(_ sender: UIButton) 
    print("Button works")
    self.dismiss(animated: false, completion: nil)


func createDialogView() 
    dialogView = UIView(frame: CGRect(x: dialogViewWidth * 0.1, y: dialogViewHeight * 0.1, width: dialogViewWidth * 0.8, height: dialogViewHeight * 0.8))
    dialogView.layer.borderWidth = 1
    dialogView.layer.borderColor = UIColor.defaultDialogBorderColor().cgColor
    dialogView.layer.cornerRadius = 8.0
    dialogView.clipsToBounds = true
    dialogView.backgroundColor = UIColor.white

    dialogView.translatesAutoresizingMaskIntoConstraints = false
    self.view.addSubview(dialogView)



func createTitleLabel() 
    let title = titleDialog
    titleLabel = UILabel(frame: CGRect(x: 0, y: 0, width: dialogView.frame.width, height: 50))
    titleLabel.backgroundColor = UIColor(red: 0.957, green: 0.957, blue: 0.949, alpha: 1.0)
    titleLabel.numberOfLines = 1
    titleLabel.textAlignment = .center
    titleLabel.font = UIFont.boldSystemFont(ofSize: 21.0)
    titleLabel.text = title
    titleLabel.textColor = UIColor.defaultDialogTextColor()

    titleLabel.translatesAutoresizingMaskIntoConstraints = false
    self.dialogView.addSubview(titleLabel)



func createOkButton() 
    okButton = UIButton(frame: CGRect(x: dialogView.frame.width - 60, y: 0, width: 60, height: 50))
    okButton.backgroundColor = UIColor.clear
    okButton.setTitle("X", for: UIControlState.normal)

    okButton.addTarget(self, action: #selector(self.okButtonAction), for: .touchUpInside)
    okButton.setTitleColor(UIColor.defaultButtonTextColor(), for: UIControlState())
    self.titleLabel.addSubview(okButton)



let sharksText = "\n\n\"People protect what they love.\"\nJacques Yves Cousteau\n\nOur beautiful sharks\n\nSharks are jawed fish with paired fins and two-chambered hearts. The class is divided into two subclasses: Elasmobranchii or elasmobranchs, (sharks, rays and skates) and Holocephali (chimaeras, sometimes called ghost sharks). Elasmobranch means that they have arch-shaped gills. Unlike the bony fishes (teleosts), chondrichthyes' skeletons are made of cartilage and instead of bony scales, they have skin that is covered in dermal denticles, like small teeth, making their skin very rough and producing a highly efficient hydrodynamic surface.\n\nShark families include the ocean’s prime predators and this has earned them an unjustified reputation for being dangerous, mindless killers – perhaps they are if you are a fish, but generally not if you are a human. In fact very few of the 460 or so species are dangerous to man and none actively targets human meat for food.\n\nDeciding which species of shark are dangerous is more complicated than you may think because the statistics need some interpretation. Very few observers would consider, for example, a nurse shark to be particularly dangerous, but actually quite a few people are bitten by them; not because they are aggressive (quite the opposite), but because so many people try to handle them. The same is true for blacktip sharks, but in my experience you’d be very lucky ever to get close enough to one in the wild; they are very shy and retiring.\n\nTechnically, any shark over about 1.8 metres in length (about 6 feet) can be a danger to man, purely because of its size, teeth and strong jaws. That said, we know that the largest shark (indeed the largest fish) in the seas today, the Whale Shark, is mild mannered and placid – although they too have teeth. Whale Sharks cruise the oceans and eat little that is bigger than plankton. The size of these sharks makes them fearless and easy to approach - sometimes to their disadvantage!\n\nIf one were to name the species of shark that could be considered dangerous, it could contain a list of five:\n\n- The short fin mako shark (length up to 3.9 metres) is a fearsome predator, but has only ever been blamed for around eight human deaths. Attacks by these fish are generally provoked by fishermen catching them on hooks.\n\n- The oceanic whitetip shark (length up to 3.9 metres) has probably only been proven to be responsible for one or two human fatalities (including one in the Red Sea in June 2009 and one more in December 2010) and maybe six or so other attacks.  But again, we need to examine the statistics. These numbers may be so low because they live in deep water and tend to leave little evidence of their prey and, so, no one to report the incident. In reality, this may be the shark responsible for many deaths of shipwrecked servicemen in the Pacific during the Second World War, although the slightly smaller Blue Shark, which also has a rounded first dorsal fin, often got the blame.\n\n- The great white shark (length up to 7 metres) has the reputation of a gratuitous killer, mainly from movies and somewhat over-dramatic documentaries. They are, of course, big, powerful animals and deserve great respect. However, most great white attacks on humans (of which there have been a little over 400) are due to mistaken identity or curiosity. Great whites eat seals and sea lions, not humans; we are simply not on their menu. This is why so many people survive great white attacks; their first strike is to determine if the target is food and, once they discover we are not, they tend not to come back. Of course, one bite from this magnificently armed predator is sometimes enough – a “taste bite” can remove 10 kilos of flesh!\n\n- The tiger shark shark (length up to 5 metres) is a highly indiscriminate feeder. Unlike its cousins, once it attacks it tends to finish the job, no matter what it has chosen to target. This may be why there are a number of people around the world with a story to tell about being attacked by a great white, but very few that have survived the attentions of a tiger shark.\n\n- The bull shark (length up to 3.4 metres) ranks reasonably high as it lives in the sort of water that humans like to bathe in – shallow, warm, fresh or salty; this brings it into contact with more humans than most other species. These sharks can be very aggressive and it is likely that tiger sharks get the blame for at least some of their attacks.\n\n- Sharks attack humans very infrequently; it is very easy to get the threat way out of proportion. While there are somewhere in the region of 50, maybe 100, shark attacks around the world each year, only around 5, maybe 10, are fatal (statistics from the International Shark Attack File, 1990-2008). You have about a one-in-two-million chance of drowning in the sea or dying at the beach; you have about a one-in-twelve-million chance of being attacked by a shark. Consider that more people die of bee stings, twice as many are killed by lightning in the USA alone and many hundreds of times more are bitten by dogs. And it would be wrong to think that all shark attacks involve horrific injuries; an attack may simply be a bump or a rasping with the upper teeth."

这是它的样子:

这是我的层次结构的图像

【问题讨论】:

您的标题标签是否覆盖在您的按钮上并阻止按钮接收触摸?您可以通过更改标签背景颜色或使用“调试视图层次结构”功能来检查这一点。或者您可以将标签的 isUserInteractionEnabled 更改为 false 以查看。 对不起,你可以忽略它——我把标题设置和正文标签设置弄混了。我仍然建议做“调试视图层次结构”的事情。 基于按钮操作,print("Button works") 有效吗? 是否打印?或者,它不是在调用动作吗? 当我将@AhmadF 的答案应用于您的上述代码时,我能够使其工作。如果它不适合您,那么您可能在发布后更改了代码。 【参考方案1】:

createOkButton()中,将按钮添加到dialogView而不是添加到titleLabel会更合适:

func createOkButton() 
    okButton = UIButton(frame: CGRect(x: dialogView.frame.width - 60, y: 0, width: 60, height: 50))
    okButton.backgroundColor = UIColor.clear
    okButton.setTitle("X", for: UIControlState.normal)

    okButton.addTarget(self, action: #selector(self.okButtonAction), for: .touchUpInside)
    okButton.setTitleColor(UIColor.defaultButtonTextColor(), for: UIControlState())
    self.dialogView.addSubview(okButton) // instead of self.titleLabel.addSubview(okButton)

另外,为了确保按钮位于dialogView 中的其他子视图之上 - 例如titleLabel-,您可以添加到方法中:

dialogView.bringSubview(toFront: okButton)

如果应用上述代码不起作用 - 这会很奇怪 - 我建议尝试将 okButton 作为子视图添加到 ViewController 的主视图中,而不是 dialogView (此时,你应该修复它的框架...)。

【讨论】:

我刚刚创建了基于视图的 OKButton,而不是 dialogView 和相同的结果。这似乎是按钮的问题。我错过了代表还是什么? 虽然我认为这并不重要,但我在 splitView 控制器上运行此视图并使用 self.splitViewController?.preferredDisplayMode = UISplitViewControllerDisplayMode.primaryOverlay @DavidSanford 真的很奇怪!它应该可以工作......我建议分享你的项目(也许是保管箱),这样我就可以检查它,这真的让我很困惑! 当然,给我一点时间,因为这是一个大项目,我想把它分解,只分享这一部分。【参考方案2】:

由于您的按钮是标题的子视图,因此您需要为标题标签启用 userInteraction:

titleLabel.isUserInteractionEnabled = true

正如@AhmadF 指出的那样,这是一种奇怪的布局方式。您通常不会将按钮设为标签的子视图。事实上,Interface Builder 不会让你这样做。因此,正如@AhmadF 在他的回答中所描述的那样,将您的按钮设置为 dialogView 的子视图会更有意义。

【讨论】:

问候 vacawama!您的答案似乎是正确的...但是,您不认为将按钮作为子视图添加到标签中在逻辑上有点奇怪吗?例如,您将无法在 Interface Builder 中做这样的事情,这可能会以某种方式解释我的观点。请指教。 @AhmadF,是的。这是一件奇怪的事情。你是对的,IB 不会让你那样构建它。

以上是关于程序化 UIView 内的程序化 UIButton 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

UIScrollview内的UIView内的UIButton,ARC问题

UIView 内的 UIButton 目标操作

更改 UIView 内的 UIButton 框架

UIScrollView 内的 UIView 上的 UIButton

UIVIew 中的 UIButton 不在 iPhone 应用程序中居中

从 UIButton 按下处理程序获取关联 UIView 的最简洁方法