如何以编程方式呈现来自UIVIew

时间:2018-05-07 07:30:24

标签: ios swift uiviewcontroller ibaction swiftmessages

我正在使用一个类,它是MessageViewSwift Message Library)的子类,它继承自UIView。在里面,我有一个UIButton,我希望通过它以编程方式呈现另一个ViewController

以下是我的代码:

import Foundation
import SwiftMessages
import UIKit

class MyClass: MessageView {

    var hideBanner: (() -> Void)?


    @IBAction func helpButtonPressed(_ sender: UIButton) {
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "newViewController") as! NewViewController
        self.present(newViewController, animated: true, completion: nil)

    @IBAction func tryAgainButtonPressed(_ sender: UIButton) {
        hideBanner?()
    }

    open override func awakeFromNib() {

    }

}

我试过这个,但由于UIView没有现有方法,因此无法正常工作。

7 个答案:

答案 0 :(得分:1)

.presentUIViewController类中的方法,这就是您无法从UIView类提供视图控制器的原因。

要实现此目的,请获取根视图控制器并按如下方式显示控制器:

let appDelegate  = UIApplication.shared.delegate as! AppDelegate
let viewController = appDelegate.window!.rootViewController as! YourViewController
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "newViewController") as! NewViewController
        viewController .present(newViewController, animated: true, completion: nil)

答案 1 :(得分:1)

首先使用此功能获得热门ViewController。然后,您可以展示自己的viewController

if var topController = UIApplication.sharedApplication().keyWindow?.rootViewController {
    while let presentedViewController = topController.presentedViewController {
        topController = presentedViewController
    }

    // topController now can use for present.
    let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let newViewController = storyBoard.instantiateViewController(withIdentifier: "newViewController") as! NewViewController
    topController.present(newViewController, animated: true, completion: nil)
}

答案 2 :(得分:1)

iOS惯例是只有params个呈现另一个ViewController

所以上面的答案 - ViewController找到的当前View通过ViewController 将会起作用但是非常反模式。

首选方式是:

  • 您的UIApplication.sharedApplication().keyWindow?....视图仅包含演示文稿代码
  • 您必须拥有一个ViewController,其中包含对此MyClass视图
  • 的引用
  • 此ViewController具有MyClass
  • 从那里,您可以呈现下一个ViewController

答案 3 :(得分:1)

试试这个 #simple 代码。

import Foundation
import SwiftMessages
import UIKit

class MyClass: MessageView {

var hideBanner: (() -> Void)?


@IBAction func helpButtonPressed(_ sender: UIButton) {
    let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let newViewController = storyBoard.instantiateViewController(withIdentifier: "newViewController") as! NewViewController
    UIApplication.shared.keyWindow?.rootViewController?.present(newViewController, animated: true, completion: nil)
}

@IBAction func tryAgainButtonPressed(_ sender: UIButton) {
    hideBanner?()
}

open override func awakeFromNib() {

}

}

答案 4 :(得分:1)

以下是使用委托模式的示例代码。

class YourViewController: UIViewController {
  var yourView: MyClass // may be outlet

    override func viewDidLoad() {
        super.viewDidLoad()

        yourView.delegate = self
    }

}

protocol MyClassDelegate:class {
    func tryAgainButtonDidPressed(sender: UIButton)
}

class MyClass: MessageView {

  weak var delegate: MyClassDelegate?


   @IBAction func tryAgainButtonPressed(_ sender: UIButton) {
        delegate?.tryAgainButtonDidPressed(sender: sender)
    }

}

答案 5 :(得分:1)

您可以通过两种方式实现这一目标

  • 协议
  • 通过在初始化视图时将该视图控制器引用到视图

答案 6 :(得分:1)

很抱歉迟到的回复。 MessageView已经为您提供了buttonTapHandler回调:

/// An optional button tap handler. The `button` is automatically
/// configured to call this tap handler on `.TouchUpInside`.
open var buttonTapHandler: ((_ button: UIButton) -> Void)?

@objc func buttonTapped(_ button: UIButton) {
    buttonTapHandler?(button)
}

/// An optional button. This buttons' `.TouchUpInside` event will automatically
/// invoke the optional `buttonTapHandler`, but its fine to add other target
/// action handlers can be added.
@IBOutlet open var button: UIButton? {
    didSet {
        if let old = oldValue {
            old.removeTarget(self, action: #selector(MessageView.buttonTapped(_:)), for: .touchUpInside)
        }
        if let button = button {
            button.addTarget(self, action: #selector(MessageView.buttonTapped(_:)), for: .touchUpInside)
        }
    }
}

会自动为您连接到button插座的任何按钮调用。因此,用于呈现另一个视图控制器的推荐方法是让呈现视图控制器在此回调中配置表示逻辑:

messageView.tapHandler = { [weak self] in
    guard let strongSelf = self else { return }
    let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let newViewController = storyBoard.instantiateViewController(withIdentifier: "newViewController") as! NewViewController
    strongSelf.present(newViewController, animated: true, completion: nil)
}

如果您的视图有多个按钮,则可以通过buttonTapHandler处理它们,因为它需要button个参数。您只需为每个按钮配置目标操作机制:

otherButton.addTarget(self, action: #selector(MessageView.buttonTapped(_:)), for: .touchUpInside)

或者您可以通过复制上述模式为每个按钮添加一个回调。