简体   繁体   中英

Programmatic UIButton inside programmatic UIView not working

I have create a programmatic UIView to display text with the appearance of a modal. I have all completed and am happy with the result, but when I press the UIButton "X", nothing happens.

I have read thru many, UIButton questions on Stackoverflow, but none of them seemed to help me.

Here is the code:

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."

}

Here is what it looks like: 在此处输入图片说明

Here is an image of my Hierarchy

在此处输入图片说明

In createOkButton() , it would be more appropriate to add the button into the dialogView instead of adding it into 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)
}

Also, to make sure that the button is on top of the other subviews in dialogView -such as titleLabel -, you could add to the method:

dialogView.bringSubview(toFront: okButton)

In case of applying the above code does not worked -which it would be weird-, I would suggest to try to add okButton as a subview to the main view of the ViewController instead of dialogView (at this point, you should restup its frame...).

Since your button is a subview of your title, you need to enable userInteraction for the title label:

titleLabel.isUserInteractionEnabled = true

As @AhmadF pointed out, this is an odd way to lay things out. You usually don't make a button the subview of a label. In fact, Interface Builder won't let you do this. So it would make more sense to make your button the subview of your dialogView as @AhmadF describes in his answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM