UIButton里面的自定义UIView类不起作用

时间:2018-03-22 13:59:09

标签: ios swift xcode uiview uibutton

我知道很多次都会问这个问题,但没有一个解决方案对我有用。

我有一个自定义的UIView类,用于显示警报消息。我添加了UIButton来关闭视图。但是,当我选中它时没有任何反应。

import UIKit
public class Alert: UIView {

    public var image: UIImage?
public var title: String?
public var message: String?
public var closeButtonText: String?

public var dialogBackgroundColor: UIColor = .white
public var dialogTitleTextColor: UIColor = .black
public var dialogMessageTextColor: UIColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
public var dialogImageColor: UIColor = UIColor(red:0.47, green:0.72, blue:0.35, alpha:1.0)
public var overlayColor: UIColor = .black
public var overlayOpacity: CGFloat = 0.66

public var paddingSingleTextOnly: CGFloat = 8
public var paddingTopAndBottom: CGFloat = 24
public var paddingFromSides: CGFloat = 8
public var seperatorHeight: CGFloat = 6

private var height: CGFloat = 0
private var width: CGFloat = 0
private var maxSize: CGSize = CGSize()
private let marginFromSides: CGFloat = 80

public lazy var imageSize: CGSize = CGSize(width: 75, height: 75)

public var overlay = false
public var blurOverlay = true

//animation duration
public var duration = 0.33

private var onComplete: (() ->  Void)?

@objc public var titleFont: UIFont =  UIFont.systemFont(ofSize: 18)
@objc public var messageFont: UIFont = UIFont.systemFont(ofSize: 15)


private lazy var backgroundView: UIView = {
    let view = UIView()
    view.alpha = 0
    return view
}()

public let dialogView: UIView = {
    let view = UIView()
    view.layer.cornerRadius = 6
    view.layer.masksToBounds = true
    view.alpha = 0
    view.clipsToBounds = true
    return view
}()

private lazy var imageView: UIImageView = {
    let view = UIImageView()
    view.contentMode = .scaleAspectFit
    return view
}()

public lazy var closeButton: UIButton = {
    let button = UIButton()
    return button
}()

private lazy var titleLabel: UILabel = {
    let label = UILabel()
    label.numberOfLines = 0
    label.textAlignment = .center
    return label
}()

private lazy var messageLabel: UILabel = {
    let label = UILabel()
    label.numberOfLines = 0
    label.textAlignment = .center
    return label
}()

@objc func closeButtonTapped(sender: UIButton){
    dismiss()
}

private func calculations() {
    height += paddingTopAndBottom
    maxSize = CGSize(width: frame.width - marginFromSides * 2, height: frame.height - marginFromSides)
}

public convenience init(title:String, message: String, image:UIImage) {
    self.init(frame: UIScreen.main.bounds)
    self.title = title
    self.message = message
    self.image = image
}

public convenience init(title:String, image:UIImage) {
    self.init(frame: UIScreen.main.bounds)
    self.title = title
    self.image = image
}

public convenience init(title: String, message: String) {
    self.init(frame: UIScreen.main.bounds)
    self.title = title
    self.message = message
}

public convenience init(message: String) {
    self.init(frame: UIScreen.main.bounds)
    paddingTopAndBottom = paddingSingleTextOnly
    paddingFromSides = paddingSingleTextOnly * 2
    self.message = message
}

override init(frame: CGRect) {
    super.init(frame: frame)
}

public required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

private func createOverlay() {
    backgroundView.frame = frame
    backgroundView.backgroundColor = overlayColor
    backgroundView.isUserInteractionEnabled = true
    addSubview(backgroundView)
    if let window = UIApplication.shared.keyWindow {
        window.addSubview(backgroundView)
    } else if let window = UIApplication.shared.delegate?.window??.rootViewController {
        window.view.addSubview(self)
    }
}

private func createBlurOverlay() {
    backgroundView.frame = frame
    //Blur Effect
    let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.dark)
    let blurEffectView = UIVisualEffectView(effect: blurEffect)
    blurEffectView.frame = frame
    blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    backgroundView.addSubview(blurEffectView)
    addSubview(backgroundView)
    if let window = UIApplication.shared.keyWindow {
        window.addSubview(backgroundView)
    } else if let window = UIApplication.shared.delegate?.window??.rootViewController {
        window.view.addSubview(self)
    }
}

private func createTitle(title: String) {
    titleLabel.font = titleFont
    titleLabel.text = title
    titleLabel.frame.origin.y = height + 2
    let titleLabelSize = titleLabel.sizeThatFits(maxSize)
    handleSize(size: titleLabelSize)
    titleLabel.frame.size = titleLabelSize
    titleLabel.textColor = self.dialogTitleTextColor
    dialogView.addSubview(titleLabel)
}

private func createMessage(message: String) {
    messageLabel.font = messageFont
    messageLabel.text = message
    messageLabel.frame.origin.y = height
    let messageLabelSize = messageLabel.sizeThatFits(maxSize)
    messageLabel.frame.size = messageLabelSize
    messageLabel.textColor = self.dialogMessageTextColor
    handleSize(size: messageLabelSize)
    dialogView.addSubview(messageLabel)
}


private func createImage(image: UIImage) {
    imageView.image = image.withRenderingMode(.alwaysTemplate)
    imageView.frame.origin.y = height
    imageView.frame.size = imageSize
    imageView.tintColor = self.dialogImageColor
    handleSize(size: imageSize)
    dialogView.addSubview(imageView)
}

private func createButton(){
    closeButton.setTitle("Close", for: .normal)
    closeButton.tintColor = UIColor.white
    closeButton.frame.origin.y = height + 20
    let closeButtonSize = CGSize(width: width - 60, height: 60)
    closeButton.frame.size = closeButtonSize
    closeButton.layer.cornerRadius = 6
    closeButton.backgroundColor = Color.NavigationBar.tintColor
    closeButton.isUserInteractionEnabled = true
    handleSize(size: closeButtonSize)
    dialogView.addSubview(closeButton)
}

private func createDialog() {
    centerAll()
    height += paddingTopAndBottom
    dialogView.frame.size = CGSize(width: width, height: height)
    dialogView.backgroundColor = self.dialogBackgroundColor
    dialogView.isUserInteractionEnabled = true
    addSubview(dialogView)
    self.dialogView.center = self.center
    self.dialogView.transform = CGAffineTransform(scaleX: 1.15, y: 1.15)
    if let window = UIApplication.shared.keyWindow {
        window.addSubview(dialogView)
        closeButton.addTarget(self, action: #selector(closeButtonTapped(sender:)), for: .touchUpInside)
    } else if let window = UIApplication.shared.delegate?.window??.rootViewController {
        UIApplication.topViewController()?.view.addSubview(self)
        window.view.addSubview(self)
        closeButton.addTarget(self, action: #selector(closeButtonTapped(sender:)), for: .touchUpInside)
    }
}

private func centerAll() {
    if ((messageLabel.text) != nil) {
        messageLabel.frame.origin.x = (width - messageLabel.frame.width) / 2
    }

    if ((titleLabel.text) != nil) {
        titleLabel.frame.origin.x = (width - titleLabel.frame.width) / 2
    }

    if ((imageView.image) != nil) {
        imageView.frame.origin.x = (width - imageView.frame.width) / 2
    }
    closeButton.frame.origin.x = (width - closeButton.frame.width) / 2

}

private func handleSize(size: CGSize) {
    if width < size.width + paddingFromSides * 2 {
        width = size.width + paddingFromSides * 2
    }
    if paddingTopAndBottom != paddingSingleTextOnly {
        height += seperatorHeight
    }
    height += size.height
}

private func showAnimation() {
    UIView.animate(withDuration: duration, animations: {
        if self.overlay {
            self.backgroundView.alpha = self.overlayOpacity
            self.dialogView.transform = CGAffineTransform(scaleX: 1, y: 1)
        }
        self.dialogView.alpha = 1
    })

}
public func show() {
    if let complete = onComplete {
        self.onComplete = complete
    }
    calculations()

    if self.overlay {
        if blurOverlay {
            createBlurOverlay()
        } else {
            createOverlay()
        }
    }

    if let img = image {
        createImage(image: img)
    }
    if let title = title {
        createTitle(title: title)
    }
    if let message = message {
        createMessage(message: message)
    }
    createButton()
    createDialog()

    showAnimation()

}

public func dismiss(){
    UIView.animate(withDuration: duration, animations: {
        if self.overlay {
            self.backgroundView.alpha = 0
        }
        self.dialogView.transform = CGAffineTransform(scaleX: 1.15, y: 1.15)
        self.dialogView.alpha = 0
    }, completion: { (completed) in
        self.dialogView.removeFromSuperview()
        if (self.overlay)
        {
            self.backgroundView.removeFromSuperview()
        }
        self.removeFromSuperview()
        if let completionHandler = self.onComplete {
            completionHandler()
        }
    })
}
}

我如何创建警报;

let alert = Alert(title: "hata",message: "hata mesajı ekrana basıldı", image: #imageLiteral(resourceName: "error"))
alert.show()

如果我在UIViewController(我创建这个UIView的地方)中声明目标为

Alert.closeButton.addTarget(self, action: #selector(closeButtonTapped(sender:), for: .touchUPInside)

并在UIViewController中创建函数它正在工作。我无法弄清楚为什么它在自定义课程中不起作用。

所以我的问题是如何在选中按钮时关闭警报视图?

我尝试了下面的解决方案,但没有为我工作;

UIButton target action inside custom class

3 个答案:

答案 0 :(得分:2)

假设这些行在函数内部 - 例如由于按钮点击:

@IBAction func didTap(_ sender: Any) {
    let alert = Alert(title: "hata",message: "hata mesajı ekrana basıldı", image: #imageLiteral(resourceName: "error"))
    alert.show()
}

您正在创建Alert类的实例,在其中调用.show()函数,然后它超出范围。

因此,只要该函数存在,alert就不再存在,并且其中没有代码可以运行。

你需要有一个类级变量来显示它:

class MyViewController: UIViewController {

    var alert: Alert?

    @IBAction func didTap(_ sender: Any) {
        alert = Alert(title: "hata",message: "hata mesajı ekrana basıldı", image: #imageLiteral(resourceName: "error"))
        alert?.show()
    }

}

以下是&#34;错误方式&#34;和正确的方式&#34;处理您的Alert视图:https://github.com/DonMag/EmreTest

答案 1 :(得分:-1)

查看此代码

1-在UIView类中调用IBAction

import UIKit

public class Alert: UIView {

    public lazy var closeButton: UIButton = {
        let button = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        button.backgroundColor = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
        return button
    }()

    func createDialog() {
          closeButton.addTarget(self, action: #selector(self.closeButtonTapped(sender:)), for: .touchUpInside)
        self.addSubview(closeButton)
    }

    @objc func closeButtonTapped(sender: UIButton){
        print("Call   1")
    }
}
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let alert = Alert(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        alert.createDialog()

        self.view.addSubview(alert)
    }

}

2-在UIViewController类中调用IBAction

import UIKit

public class Alert: UIView {

    public lazy var closeButton: UIButton = {
        let button = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        button.backgroundColor = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
        return button
    }()

    func createDialog() {
        //  closeButton.addTarget(self, action: #selector(self.closeButtonTapped(sender:)), for: .touchUpInside)
        self.addSubview(closeButton)
    }

    @objc func closeButtonTapped(sender: UIButton){
        print("Call   1")
    }
}
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let alert = Alert(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        alert.createDialog()
        alert.closeButton.addTarget(self, action: #selector(self.closeButtonTappedController(_:)), for: .touchUpInside)
        self.view.addSubview(alert)
    }

    @IBAction func closeButtonTappedController(_ sender:UIButton){
        print("Call   2")

    }
}

答案 2 :(得分:-2)

在自定义swift类中导入UIKit。

导入UIKit