簡體   English   中英

如何添加UIViewController作為在以編程方式創建的UIView中創建的UIButton操作的目標?

[英]How to add UIViewController as target of UIButton action created in programmatically created UIView?

我以編程方式創建了一個UIView並添加了一個UIButton作為它的子視圖。
我希望UIViewController成為該按鈕操作的目標。
我該怎么辦?
如果它是由Interface Builder創建的,那么使用IBAction很容易

如果您以編程方式將按鈕添加到UIView的子類,那么您可以通過以下兩種方式之一執行此操作:

  1. 您可以使按鈕成為視圖的屬性,然后在實例化視圖的viewController中,您可以設置按鈕的目標,如下所示:

     [viewSubclass.buttonName addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside]; 

    這會將按鈕的目標設置為viewController.m中buttonTapped的方法

  2. 您可以在子視圖中創建協議,父視圖控件將遵循該協議。 在您的視圖中,當您添加按鈕時,將其設置為在視圖中調用方法。 然后從該視圖中調用delegate方法,以便viewController可以響應它:

在頂部您的視圖子類.h創建協議:

@protocol ButtonProtocolName

- (void)buttonWasPressed;

@end

為委托創建屬性:

@property (nonatomic, assign) id <ButtonProtocolName> delegate;

在子類.m中設置按鈕選擇器:

[button addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];

在buttonTapped:方法中調用委托方法:

- (void)buttonTapped:(id)sender {
    [self.delegate buttonWasPressed];
}

在viewController.h中,您需要確保它符合協議:

@interface someViewController : UIViewController <SomeButtonProtocolName>

在初始化子視圖時,在viewController.m中,您必須設置委托:

SomeView *view = ... // Init your view
// Set the delegate
view.delegate = self;

最后,將delegate方法buttonWasPressed添加到viewController.m:

- (void)buttonWasPressed {
    // Put code here for button's intended action.
}

更新以提供Swift示例

// Simple delegate protocol.
protocol SomeViewDelegate: class {
  // Method used to tell the delegate that the button was pressed in the subview.
  // You can add parameters here as you like.
  func buttonWasPressed()
}

class SomeView: UIView {
  // Define the view's delegate.
  weak var delegate: SomeViewDelegate?

  // Assuming you already have a button.
  var button: UIButton!

  // Once your view & button has been initialized, configure the button's target.
  func configureButton() {
    // Set your target
    self.button.addTarget(self, action: #selector(someButtonPressed(_:)), for: .touchUpInside)
  }

  @objc func someButtonPressed(_ sender: UIButton) {
    delegate?.buttonWasPressed()
  }
}

// Conform to the delegate protocol
class SomeViewController: UIViewController, SomeViewDelegate {
  var someView: SomeView!

  func buttonWasPressed() {
    // UIViewController can handle SomeView's button press.
  }
}

另外,這是一個使用閉包而不是委托的快速示例。 (這也可以使用塊在ObjC中實現。)

// Use typeAlias to define closure
typealias ButtonPressedHandler = () -> Void

class SomeView: UIView {
  // Define the view's delegate.
  var pressedHandler: ButtonPressedHandler?

  // Assuming you already have a button.
  var button: UIButton!

  // Once your view & button has been initialized, configure the button's target.
  func configureButton() {
    // Set your target
    self.button.addTarget(self, action: #selector(someButtonPressed(_:)), for: .touchUpInside)
  }

  @objc func someButtonPressed(_ sender: UIButton) {
    pressedHandler?()
  }
}

class SomeViewController: UIViewController {
  var someView: SomeView!

  // Set the closure in the ViewController
  func configureButtonHandling() {
    someView.pressedHandler = {
      // UIViewController can handle SomeView's button press.
    }
  }
}

您可以向按鈕添加目標和操作。

[button addTarget:controller/self action:@selector(onTapButton) forControlEvents:UIControlEventTouchUpInside];

目標是控制器所以如果你想在當前控制器中處理觸摸事件使用自己。 另外,你應該有一個指向控制器obj的指針/引用,並使用該引用而不是self。 onTapButton是選擇器,當用戶點擊按鈕時將調用該選擇器。 onTapButton不帶任何參數,如果要與參數一起使用onTapButton:

- (IBAction/void)onTapButton{
}
-(IBAction/void)onTapButton:(id)sender{
}

注意:更好的方法是處理這是使用委托模式,在自己的類中有目標,然后調用委托,並且控制器應該實現該委托。 直接參考控制器並不是一種好的做法。

[buttonName addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];

現在,如果你正在使用UINavigationController,你的buttonPressed函數將是

- (void)buttonPressed:(id)sender
{
    NewViewController *newVC = [NewViewController new];
    [self.navigationController pushViewController:newVC animated:YES];

}

如果你沒有使用導航控制器

- (void)buttonPressed:(id)sender
{
    NewViewController *newVC = [NewViewController new];
    [self presentViewController:newVC animated:YES completion:nil];

}

我們也可以在沒有代表的情況下實現這一點。

CustomUIView.m類中,實現以下方法: -

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    NSArray *viewsInNib = [[NSBundle mainBundle]loadNibNamed:@"AddressAlertView" owner:self options:nil];
    for (id view in viewsInNib) {
        if ([view isKindOfClass:[self class]]) {
            self = view;
            break;
        }
    }

    return self;
}

說明: - 在initWithFrame方法中,我正在加載當前的nib。 加載nib意味着初始化它包含的所有子視圖。 獲取同一類的完全初始化視圖並分配給self。 返回包含完全初始化uiview的self。

在你的viewcontroller.m文件中,編寫下面的代碼來添加自定義uiview並設置按鈕的目標: -

UIWindow *mainWindow = [[[UIApplication sharedApplication]delegate]window];

AddressAlertView *objAddressAlertView = [[AddressAlertView alloc] initWithFrame:mainWindow.bounds];
[objAddressAlertView.btnCross addTarget:self
                                 action:@selector(dummy)
                       forControlEvents:UIControlEventTouchUpInside];
if (objAddressAlertView)
    [mainWindow addSubview:objAddressAlertView];

對於Swift 4

class MyView: UIView {

 weak var delegate: MyBtnDelegate?

 var myBtn: UIButton = {
    let myCustomButton = UIButton()

    // Button UI code goes here

    myCustomButton.addTarget(self, action: #selector(saveData), for: .touchUpInside)
    return myCustomButton
}()


@objc func saveData() {

delegate?.doSomething()

}

在ViewController中

protocol MyBtnDelegate: class {
func doSomething()
}

class ViewController: UIViewController, MyBtnDelegate {
var customView = MyView()

 override func viewDidLoad() {
    super.viewDidLoad()
    customView.delegate = self  // Unless you add this line code won't be working
}

func doSomething() {

//Do whatever you want

  }
}

希望這可以幫助。 快樂編碼:]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM