TapGesture 添加到 UIView+SomeCategory。我如何使用这个添加到我的 UIViewController 的 UIView?

TapGesture added to UIView+SomeCategory. How can I use this UIView that is added to my UIViewController?

我有一个自定义的 UIView。我在这个 UIView 中添加了一个 tapGestureRecognizer。不是通过 UIViewController,而是在 UIView+Category class 内。我正在尝试在点击此 UIView 时使用 presentViewController() 。这是一个 UIView class,它不允许 presentViewController()。我知道只有 UIViewController 允许调用此函数。那么我是否错误地构建了我的项目?如果我只是将 tapGestureRecognizer 添加到此 UIView 而不是使用类别而是直接从 UIViewController 中添加,会更好吗?这个 UIView 也将在其他地方使用,所以如果我能做到这一点,它将为我节省大量代码。提前致谢。

您从错误的角度来处理问题。在代码中实现 MVC, or Model-View-Controller 模式时遵循良好的标准很重要。将 UIViews 视为只应管理视图布局代码的哑对象(有时它是自己的自定义动画)。他们不应该管理 ViewController 逻辑,因为 ViewController 逻辑超出了他们的范围。他们很愚蠢,对与视图无关的任何事情一无所知。

更好的方法是创建一个 UIViewController 子类来管理视图的点击手势(您可以在 viewDidLoad 下添加点击手势识别器)。然后在需要时从其他视图控制器子类化 ViewController。

希望对您有所帮助。

presentViewController(),您必须需要UIViewController对象。我想建议你,你可以将 UIView 声明为 Apple 提供的 UITableView。意味着您可以创建一个 UIView class 并在 class 中添加 UITapGestureDelegate。和 type cast 这个 class 在任何你需要的地方就像 UITableView (它可能来自故事板或以编程方式)。

现在在创建的 class 中声明一个 Delegate 方法。并在需要时将此方法定义为当前 UIViewController。所以现在发生了什么,当你点击 UIView 时它会调用 UITapGesture selector 方法。在该选择器方法中,借助 delegate 方法响应转移到当前 UIViewController class.

现在您可以 presentUIViewController() 当前 class。

因此在整个场景中,您只需在当前 class 中定义 Delegate 方法,而无需在不同的 class 中编写相同代码的次数。这与 Apple 为 UITableView.

提供的流程相同

uiview-tutorial-for-ios-how-to-make-a-custom-uiview-in-ios-5-a-5-star-rating-view

本教程将帮助您创建自定义 UIView。 希望对你有帮助。

如果你想要这样,那么这可能对你有帮助.. 在您的视图中创建一个 appdelegate 对象 class

#import "AppDelegate.h"
AppDelegate *delegateObject = [[UIApplication sharedApplication] delegate];

然后

[delegateObject.window.rootViewController presentViewController:destinationControllerObject animated:YES completion:nil];

肮脏的方式,但会奏效。

有两种直接的方法可以做到这一点 1) 通知(提供的示例是用 ObjC 编写的) 2) 委托(提供的示例是用 Swift 编写的)

1) 使用NSNotificationCenter 通知UIViewController 视图属于

在您的 UIView+Category 中定义了手势识别处理程序,post 通知并在您的 UIViewController 中添加一个 Observer

在 UIViewController 中

// Define it at the top of your view controller
#define kViewDidClick @"ViewDidClick"

 - (void)viewDidLoad {
     ...

     [[NSNotificationCenter defaultCenter]       
             addObserver: self 
                selector: @selector(presentVC:) 
                    name: kViewDidClick 
                  object: nil]; 
}

- (void)presentVC: (NSNotification *)notification {
    [self.presentViewController: vc animated: false completion: nil];
}

在你处理手势的 UIView+Category 中(现在我假设它叫做 handleGesture)

-(void) handleGesture: (UIGestureRecognizer *)gestureRecognizer {
    [[NSNotificationCenter defaultCenter] postNotificationName: kViewDidClick object: nil];
}

2) 您需要定义一个 class 来处理手势和协议。这样你就可以很容易地处理你所有的手势,而不需要在你的 UIView 或 UIViewController 中定义一些方法来处理手势,每次你想处理手势时

GestureHandlerHelper.swift

import UIKit

/**
Handle gesture recognized by a UIView instance
*/

class GestureHandlerHelper {
var delegate: SelectionDelegate?

// MARK: Initializer
init(delegate: SelectionDelegate) {
    self.delegate = delegate
}

// MARK: Gesture Handler

/**
Handle gesture recognized by a UIView instance
*/
@objc func handleGesture(gestureRecongnizer: UIGestureRecognizer) {
    println(self)
    println(__FUNCTION__)
    println(gestureRecongnizer)

    if .Ended == gestureRecongnizer.state {
        if nil != delegate? {
            delegate?.didClick(gestureRecongnizer)
        }
    }
  }
}

SelectionDelegate.swift

/**
 Define a general rule for classes that handle gesture on views
 */
protocol SelectionDelegate {
    func didClick(gestureRecognizer: UIGestureRecognizer)
}

在你的 UIViewController 中

class ViewController : UIViewController {
  ... 
  override func loadView() {
        self.view = View(frame: UIScreen.mainScreen().bounds,
          gestureHandlerHelper: GestureHandlerHelper(delegate: self))
  }
  ... 
}

extension ViewController : SelectionDelegate {

    func didClick(gestureRecognizer: UIGestureRecognizer) {
        self.presentViewController(SomeViewController(), animated: false, completion: nil)
     }
}

在你的 UIView 中

init(frame: CGRect, gestureHandlerHelper: GestureHandlerHelper) {
      ... 
    var tapGestureRecognizer = UITapGestureRecognizer(target: gestureHandlerHelper, action: "handleGesture:")
      ...
}