UIButton
があります。 2つのサブビューがあります。次に電話する:
[createButton addTarget:self action:@selector(openComposer) forControlEvents:UIControlEventTouchUpInside];
覆われていないがそのサブビューの1つであるUIButton
の部分をタップすると、正常に機能します。ただし、代わりにサブビューの1つをタップしても、アクションはトリガーされません。
両方のサブビューに、.userInteractionEnabled
はYES
に設定されます。
両方のサブビューは、UIViews
とframe
を持つプレーンbackgroundColor
sです。
タップを取得してUIView
をUIButton
に「パススルー」するにはどうすればよいですか?
ありがとう
EDIT: UIControlEventTouchDownが必要なため、UIControlEventsを使用する必要があります。
編集2:
ボタンのコードは次のとおりです。
@interface CreateButton ()
@property (nonatomic) Theme *theme;
@property (nonatomic) UIView *verticle;
@property (nonatomic) UIView *horizontal;
@property (nonatomic) BOOL mini;
@end
@implementation CreateButton
#pragma mark - Accessors
- (UIView *)verticle {
if (! _verticle) {
_verticle = [[UIView alloc] init];
_verticle.backgroundColor = [self.theme colorForKey:@"createButtonPlusBackgroundColor"];
_verticle.userInteractionEnabled = NO;
}
return _verticle;
}
- (UIView *)horizontal {
if (! _horizontal) {
_horizontal = [[UIView alloc] init];
_horizontal.backgroundColor = [self.theme colorForKey:@"createButtonPlusBackgroundColor"];
_verticle.userInteractionEnabled = NO;
}
return _horizontal;
}
#pragma mark - Init
- (instancetype)initWithTheme:(Theme *)theme frame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_theme = theme;
self.layer.cornerRadius = roundf(frame.size.width / 2);
self.layer.shadowColor = [UIColor blackColor].CGColor;
self.layer.shadowOpacity = .1f;
self.layer.shadowOffset = CGSizeZero;
self.layer.shadowRadius = 15.f;
self.backgroundColor = [self.theme colorForKey:@"createButtonBackgroundColor"];
[self addSubview:self.verticle];
[self addSubview:self.horizontal];
[self addTarget:self action:@selector(animate) forControlEvents:UIControlEventTouchDown];
[self addTarget:self action:@selector(animate) forControlEvents:UIControlEventTouchUpInside];
[self addTarget:self action:@selector(animate) forControlEvents:UIControlEventTouchUpOutside];
}
return self;
}
#pragma mark - Actions
- (void)animate {
[UIView animateWithDuration:0.2 delay:0 usingSpringWithDamping:0.4 initialSpringVelocity:8 options:kNilOptions animations:^{
if (self.mini) {
self.transform = CGAffineTransformMakeScale(1.0, 1.0);
self.mini = NO;
} else {
self.transform = CGAffineTransformMakeScale(0.90, 0.90);
self.mini = YES;
}
} completion:nil];
}
#pragma mark - UIView
- (void)layoutSubviews {
CGSize size = self.bounds.size;
NSInteger width = 3;
NSInteger verticleInset = 12;
self.verticle.frame = CGRectMake((size.width - width) / 2, verticleInset, width, size.height - (verticleInset * 2));
self.horizontal.frame = CGRectMake(verticleInset, (size.height - width) / 2, size.width - (verticleInset * 2), width);
}
@end
サブビューのuserInteractionEnabled
をNO
に設定すると、タッチがそれらを通過してボタンに到達します。
また、horizontal
プロパティのレイジーローダーで_verticle.userInteractionEnabled = NO;
を_horizontal.userInteractionEnabled = NO;
に変更してください。これはタイプミスだと思います。
次のようなコードを使用して(「ViewControllerFilterCategory」を独自のもの+ nibNameに置き換えて)、サブビューとしてビューを追加する前に、現在のコントローラーの子コントローラーとしてnib(子1)からコントローラーを追加してください。次に、iOSは、期待どおりに子コントローラーにアタッチされたアクションを呼び出します。
let vcCats = ViewControllerFilterCategory(nibName: "ViewControllerFilterCategory", bundle: Bundle.main);
self.addChildViewController(vcCats);
self.view.addSubview(vcCats.view);
追伸サブビューを削除する前に、「removeFromParentViewController」を呼び出すことを忘れないでください(以下を参照)。
@IBAction func onCanceled(_ sender: Any) {
self.removeFromParentViewController()
self.view.removeFromSuperview()
}
私はこの問題に直面しました。
私の場合、ペン先をサブビューとしてロードしました。
_UIViewController *vc = [[[NSClassFromString(@"nib_controller") alloc] initWithNibName:@"nib_name" bundle:nil] autorelease];
[self.view addSubview:vc.view];
_
Nibビュー(vc.view)では、すべてのボタンがアクションを呼び出していませんでした。
_[(UIButton*)[self.view viewWithTag:button_tag] addTarget:self action:@selector(btnActions:) forControlEvents:UIControlEventTouchUpInside];
-(IBAction)btnActions:(id)sender{
// list star buttons for bookmark
NSLog(@"btnActions tag %d", [sender tag]);
// bla bla bla
}
_
ボタンに触れることはできましたが、メソッドbtnActions
は起動されていませんでした。
それから、私は本当にシンプルで論理的なものを試しました。
親View Controllerでは、同じ名前のメソッドがあります:
_-(IBAction)btnActions:(id)sender{
// list star buttons for bookmark
NSLog(@"parent btnActions tag %d", [sender tag]);
// bla bla bla
}
_
NSLogを内部に追加して、何が起こるかを確認しました。結果はログコンソールに表示されました。
_parent btnActions tag xxx
_
これは、以前のバージョン9のiOSでは不可能でした。
しかし、今では、ビューがnibコントローラビューからロードされる場合、親ビューからメソッドにアクセスできます。
まだ混乱している人については、以下の図を参照してください
親-> A
child> B
_----------
| |
| A |
| |
----------
|
|--- -(IBAction)btnActions:(id)sender
----------
| |
| B |
| |
----------
|
|--- -(IBAction)btnActions:(id)sender (the controller have an method with same name as parent)
_
B.viewはコントローラーから追加されます
_----------
| |
| A |
| |
----------
|
|--- (touching some button -> execute this:
UIViewController *B = [[[NSClassFromString(@"B_controller") alloc] initWithNibName:@"B_name" bundle:nil] autorelease];
[self.view addSubview:B.view]; // The B.view is added as subview.
_
B.view内のボタンは、-(IBAction)btnActions
にアクションを送信します
サンプル
_[(UIButton*)[self.view viewWithTag:button_tag] addTarget:self action:@selector(btnActions:) forControlEvents:UIControlEventTouchUpInside];
_
すべてのボタンをタッチまたはクリックできるため(Xcodeシミュレーター)、すべてのボタンが正常に機能しているようです。しかし、_B.controller
_に宣言された-(IBAction)btnActions
メソッドは呼び出されていませんでした。上記のように、アクションが_A.Controller
_に送信されていることに気付くまで、これを何時間も解決し続けました。
ここでの頭痛の種は、iOSの初期バージョンではこれが不可能だったことです。
よくわかりませんが、iOS9からは、この異なる動作があると思います。
このアプリはiOS8までうまく機能していました。