我以编程方式创建了UIView
并添加了UIButton
作为子视图
我希望UIViewController
成为该按钮操作的目标
我该怎么做?
如果它是由Interface Builder创建的,那么使用IBAction
就可以轻松实现。
答案 0 :(得分:24)
如果您以编程方式将按钮添加到UIView的子类中,那么您可以采用以下两种方式之一:
您可以将按钮设为视图的属性,然后在实例化视图的viewController中,您可以按如下方式设置按钮的目标:
[viewSubclass.buttonName addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
这会将按钮的目标设置为buttonTapped的方法:在viewController.m中
您可以在子视图中创建协议,父视图控件将遵循该协议。在您的视图中,当您添加按钮时,将其设置为在视图中调用方法。然后从该视图调用委托方法,以便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;
最后,将委托方法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.
}
}
}
答案 1 :(得分:1)
您可以向按钮添加目标和操作。
[button addTarget:controller/self action:@selector(onTapButton) forControlEvents:UIControlEventTouchUpInside];
目标是控制器所以如果你想在当前控制器中处理触摸事件,请使用self。另外,你应该有一个指向控制器obj的指针/引用,并使用该引用而不是self。
onTapButton
是选择器,当用户点击按钮时将调用该选择器。 onTapButton
不接受任何参数,如果您想使用参数use onTapButton:
- (IBAction/void)onTapButton{
}
-(IBAction/void)onTapButton:(id)sender{
}
注意: 更好的方法是处理这是使用委托模式,在自己的类中有目标,然后调用委托,并且控制器应该实现该委托。直接参考控制器并不是一种好的做法。
答案 2 :(得分:0)
retry
现在,如果你正在使用UINavigationController,你的buttonPressed函数将是
[buttonName addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
如果您没有使用导航控制器而不是
- (void)buttonPressed:(id)sender
{
NewViewController *newVC = [NewViewController new];
[self.navigationController pushViewController:newVC animated:YES];
}
答案 3 :(得分:0)
我们也可以在没有代表的情况下实现这一目标。
在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的自我。
在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];
答案 4 :(得分:0)
对于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
}
}
希望这会有所帮助。编码愉快:]