[英]How to add constraints programmatically to a programmatically created UIView?
[英]How to add UIViewController as target of UIButton action created in programmatically created UIView?
我以編程方式創建了一個UIView
並添加了一個UIButton
作為它的子視圖。
我希望UIViewController
成為該按鈕操作的目標。
我該怎么辦?
如果它是由Interface Builder創建的,那么使用IBAction
很容易 。
如果您以編程方式將按鈕添加到UIView的子類,那么您可以通過以下兩種方式之一執行此操作:
您可以使按鈕成為視圖的屬性,然后在實例化視圖的viewController中,您可以設置按鈕的目標,如下所示:
[viewSubclass.buttonName addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
這會將按鈕的目標設置為viewController.m中buttonTapped的方法
您可以在子視圖中創建協議,父視圖控件將遵循該協議。 在您的視圖中,當您添加按鈕時,將其設置為在視圖中調用方法。 然后從該視圖中調用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.