如何使用 UIView、UIButton sub-类 呈现视图控制器?

How do I present a View Controller with UIView, UIButton sub-classes?

所以我创建了这个 UIButton Sub-class。它是一个可重用的组件,可以添加到任何视图控制器中。我需要通过点击按钮来呈现一个警报视图控制器。所以基本上我需要找出按钮所在的视图控制器,以便我可以将视图控制器作为参数传递。

final class ProfileButton: UIButton {

let picker = UIImagePickerController()

lazy var shadowImageView: UIImageView = {
    let imageView = UIImageView()
    imageView.contentMode = .scaleAspectFill
    imageView.image = UIImage(named: "download")
    return imageView
}()

override public init(frame: CGRect) {
    super.init(frame: frame)
    setupSelf()
    self.addTarget(self, action: #selector(profileButtonTapped), for: .touchUpInside)
}

required init?(coder: NSCoder) {
    super.init(coder: coder)
}
override public func layoutSubviews() {
    super.layoutSubviews()
    shadowImageView.layer.cornerRadius = self.frame.width/2.70
    shadowImageView.layer.masksToBounds = true
}

@objc func profileButtonTapped(){
    imageHandler(presenter: )
}

@objc func imageHandler(presenter: UIViewController!){
    let alertController = UIAlertController(title: "Profile Picture", message: "Please select your profile picture", preferredStyle: .alert)
    let okAction = UIAlertAction(title: "Photo Library", style: .default, handler: { (action: UIAlertAction!) in
        print("I am working")
    })
    let cameraAction = UIAlertAction(title: "Camera", style: .default, handler: { (action: UIAlertAction!) in
        print("I am working")
    })

    alertController.addAction(okAction)
    alertController.addAction(cameraAction)
    presenter.present(alertController, animated: true, completion: nil)
}

我实际上需要找出视图控制器,以便我可以将它传递到 imageHandler(presenter: UIViewController) 函数中。

您可以在 UIButton 中添加对控制器的 weak var 引用。更好的方法是在 UIViewController 扩展中添加处理函数,在 viewDidLoad 中添加 addTarget 而不是 UIButton 的 init(frame:)。这是一个例子:

final class ProfileButton: UIButton {
    //Remove addTarget from init(frame:)
}

class ViewController: UIViewController {
    let profileButton = ProfileButton()
    override func viewDidLoad() {
        super.viewDidLoad()
        //...
        profileButton.addTarget(self, action: #selector(imageHandler), for: .touchUpInside)
    }
}

extension UIViewController {

    @objc func imageHandler() {
        let alertController = UIAlertController(title: "Profile Picture", message: "Please select your profile picture", preferredStyle: .alert)
        let okAction = UIAlertAction(title: "Photo Library", style: .default, handler: { (action: UIAlertAction!) in
            print("I am working")
        })
        let cameraAction = UIAlertAction(title: "Camera", style: .default, handler: { (action: UIAlertAction!) in
            print("I am working")
        })

        alertController.addAction(okAction)
        alertController.addAction(cameraAction)
        present(alertController, animated: true, completion: nil)
    }
}

在这种情况下,您可以使用此扩展程序获取顶级控制器

extension UIApplication {

    class func getTopMostViewController() -> UIViewController? {
        let keyWindow = UIApplication.shared.windows.filter {[=10=].isKeyWindow}.first
        if var topController = keyWindow?.rootViewController {
            while let presentedViewController = topController.presentedViewController {
                topController = presentedViewController
            }
            return topController
        } else {
            return nil
        }
    }
}


@objc func imageHandler() {
        //...
        UIApplication.getTopMostViewController()?.present(alertController, animated: true, completion: nil)

    }