I'm creating and adding an UIButton dynamically to UIView, like:
UIButton *btn = [UIButton buttonWithType:UIButtonTypeContactAdd];
btn.frame = CGRectMake(100, 10, btn.bounds.size.width, btn.bounds.size.height);
[btn addTarget:self action:@selector(myAction:) forControlEvents:UIControlEventTouchUpInside];
[myView addSubview:btn];
This works as expected, myAction gets called. The problem begins as I add this to the outside of the visible myView, like:
btn.frame = CGRectMake(-100, 10, btn.bounds.size.width, btn.bounds.size.height);
later on, I animate myView out of the screen to make btn visible:
[UIView beginAnimations:nil context:NULL];
[myView layer].frame = CGRectMake(320, 0, 320, 48);
[UIView commitAnimations];
But the thing开发者_如何学编程 is, myAction does not get called anymore. Why? And how to fix it?
Your comment to Art's answer pretty much explains the problem. You have a button which is outside the visible area of its parent; it's irrelevant if the parent is positioned such that the button would be visible higher up on the stack. The button is getting clipped and not painted.
You have two choices.
1) Make myView's frame bigger and adjust all your coordinates appropriately. myView will always have some of its content offscreen and some onscreen and you can simply position it where you want. When the button is onscreen it will be visible. (E.g., in your code above the initial frame for myView would start at some negative value for x and extend to much wider than the iPhone screen, whereas your btn would be positioned at some positive x,y position relative to the top left of myView. Then you move myView so that, for example, it moves to 0,0, pushing some of its content offscreen while moving btn onscreen.)
2) Don't put button on myView; put it on a new view that you animate in while you are animating myView out.
Simple code for #1:
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(-100, 0, 420, 480)]; // start 100 pixels to the left
UIButton *btn = [UIButton buttonWithType:UIButtonTypeContactAdd];
btn.frame = CGRectMake(0, 10, btn.bounds.size.width, btn.bounds.size.height);
[myView addSubview:btn];
UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn1 setTitle:@"DoIt" forState:UIControlStateNormal];
btn1.frame = CGRectMake(100, 100, 50, 50);
[btn1 addTarget:self action:@selector(doit:) forControlEvents:UIControlEventTouchUpInside];
[myView addSubview:btn1];
self.view = myView;
}
- (void) doit: (id) bt {
[UIView beginAnimations:nil context:NULL];
self.view.frame = CGRectMake(100, 0, 420, 480);
[UIView commitAnimations];
}
Two things I noticed in your code:
First, since frame
is relative to a view's superview, not to the the main screen btn.frame
should not be at the offscreen location, but at the relative location in myView
. Assuming myView
is already at some negative x location, the button will be there, too.
Second, when you use Core Animation, you should set the UIView
property you want to animate, not the UIView
's layer's property.
I tested this to make sure, here's my code:
[super viewDidLoad];
offscreenView = [[UIView alloc] initWithFrame:CGRectMake(-100, 0, 200, 200)];
offscreenView.backgroundColor = [UIColor blueColor];
UIButton * btn = [UIButton buttonWithType:UIButtonTypeContactAdd];
//note we put this at 10, 10 *relative to the button's superview*
btn.frame = CGRectMake(10.0, 10.0, 50.0, 25.0);
[btn addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[offscreenView addSubview:btn];
[self.view addSubview:offscreenView];
[UIView beginAnimations:@"animateVIew" context:self];
offscreenView.frame = CGRectMake(0.0, 0.0, 200, 200);
[UIView setAnimationDuration:2.0];
[UIView commitAnimations];
Hope that helps!
CALayer have a CATransform3D property
[[btn layer] setTransform:CATransform3DMakeTranslation(-100, 0, 0)];
and you can apply CAAnimation to this property
精彩评论