4

我正在使用一个类,它是MessageView( Swift 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没有当前方法,因此无法正常工作。

4

7 回答 7

2

首先使用它获得顶部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)
}
于 2018-05-07T07:47:02.523 回答
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参数。你只需要为每个按钮配置 target-action 机制:

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

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

于 2018-05-24T12:16:42.133 回答
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() {

}

}
于 2018-05-07T08:37:31.247 回答
1

iOS 的约定是只有一个ViewControllers 代表另一个ViewController

所以上面的答案 - 在哪里View找到当前的ViewController通孔UIApplication.sharedApplication().keyWindow?.... 将起作用,但在很大程度上是一种反模式。

首选方法是:

  • 您的MyClass视图只有演示文稿代码
  • 您必须有一个引用此MyClass视图的 ViewController
  • 这个 ViewController 有@IBAction func tryAgainButtonPressed
  • 从那里,您可以呈现下一个 ViewController
于 2018-05-07T08:26:48.953 回答
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)
    }

}
于 2018-05-07T09:33:53.470 回答
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)
于 2018-05-07T07:34:27.260 回答
1

您可以通过两种方式实现此目的

  • 协议
  • 通过在初始化视图时将该视图控制器的引用提供给视图
于 2018-05-07T09:48:58.263 回答