I have a UISegmentedControl set up in my XIB. I want it to appear on viewDidLoad and if the user taps the area of the screen it's in, and then to disappear if the user taps it again or to fade out if the user leaves it alone.
In looking around for how to manage this I've found a lot of stuff about fading UIViews, but not as much on fading individual subviews, and little at all on fading elements in the XIB. I tried to adapt the UIView stuff but failed.
How can I make this work?
EDIT: Okay, I've got the appearance at viewDidLoad and the fade out working. But when the user taps the area where the UISegmentedControl is (now invisible because alpha=0), nothing happens. This is the code I'm using:
- (IBAction)tapInvisibleSegContr
//This is connected to the UISegmentedControl with the action Touch Up Inside. Until now, the segmented control has been at alpha=0 since fading after viewDidLoad.
{
self.segContrAsOutlet.alpha=1.0;
[self fadeMethodThatWorksInViewDidLoad];
NSLog(#"Yup, tapped.");
}
I'm not even getting the NSLog. I've got the action hooked up to the UISegmentedControl, with the action Touch Up Inside. What am I missing?
If it is resident in a xib, just put his alpha to 0, do the properly connections: an Outlet and an IBAction for value changed
Then in the viwDidLoad right after [super viewDidLoad] write:
[UIView animateWithDuration:1 animations:^{self.mySegOutlet.alpha = 1;}];
Inside the IBAction right after you code the answer before the last } write:
[UIView animateWithDuration:1 animations:^{self.mySegOutlet.alpha = 0;}];
This is the easiest method.
Bye
In the xib set your control's alpha to 0.0, then use UIView animation methods to animate its alpha to 1.0. For example:
[UIView animateWithDuration:1.0 animations:^{
self.segmentedControl.alpha = 1.0f;
}];
EDIT: To your problem with not getting the action called, try attaching it for the value changed control event - I don't think UISegmentedControl sends for touch up inside.
Related
I have a game that I am making and I am trying to move a button named tapMe using UIView Animation but I need it to be tapeable while it is being animated.
[UIView animateWithDuration:0.5 animations:^{
_tapMe.center = CGPointMake(xRandom, yRandom);
}];
Where xRandom and yRandom are randomly generated integers and _tapMe is connected to the button, I am certain because it does move.
When you use animateWithDuration, the button's frame is moved to its final position immediately (it will be touchable there), but the presentation layer is animated, so where you see the button during the animation is not where the touchable area will be. You either need to hit test the presentation layer, or animate the button by moving it in small increments with a timer. See the answer here for more detail, UIButton can't be touched while animated with UIView animateWithDuration
I am using the code snippet from Tito to add a custom button to my tab bar:
https://github.com/tciuro/CustomTabBar
(Subclassing UITabbarController and adding a custom button using
// .. created a UIButton *button
[self.view addSubview:button];
)
This works great with my storyboard-based app except for the case of a subview within a navigation controller with the option "Hides bottom bar on push" enabled.
This hides the tab bar as promised, but not the custom button.
Seems like the button should be added as a subview to the tab bar itself?
I tried this ugly code which did not even make the button show up:
for(UIView *view in self.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view addSubview:button];
break;
}
}
Any ideas?
UPDATE:
My solution:
In my ApplicationDelegate i define the following methods, which i call whenever needed in the viewWillAppear or viewWillDisappear methods:
-(void)hideCenterButton:(BOOL)animated
{
if(animated){
[UIView animateWithDuration:0.3
delay:0.0f
options:UIViewAnimationCurveLinear
animations:^{
CGRect frame = self.centerButton.frame;
frame.origin.x = -100;
self.centerButton.frame = frame;
}
completion:^(BOOL finished){
}];
}
}
-(void)showCenterButton:(BOOL)animated
{
if(animated){
[UIView animateWithDuration:0.35
delay:0.0f
options:UIViewAnimationCurveLinear
animations:^{
CGRect frame = self.centerButton.frame;
frame.origin.x = (self.view.superview.frame.size.width / 2) - (self.centerButton.frame.size.width / 2);
self.centerButton.frame = frame;
}
completion:^(BOOL finished){
}];
}
}
I had to set the animation's duration to 0.35s to get a smooth effect in harmony with the tab bar.
Why don't you make button your tabbar's part.
tabBarController.tabBar.addSubView(yourButton)
everything would be solve. cheers!
One easy way to handle this would be to create an instance of the button in .h of your file.
UIButton *customTabButton;
When calling the hides bottom bar on push set the button property to hidden and reset it again in the other views if the bottom bar is visible.
shareFbButton.hidden=YES;
You can check this is the viewDidLoad of all the files and put this line of code if needed to make sure you are displaying the button and hiding the button on all the pages you need.
if(self.tabBarController.tabBar.isHidden){
// set or reset the custom button visibility here
}
This is one way.
I think there are 2 ways you can got with this.
1) try to get the button into a view that is above the old top view controller and the tab bar BUT below the new top view controller that is pushed.
2) animate away the button when the new view controller is pushed.
The first will require mucking with the iOS proprietary view hierarchy which is undocumented, unsupported and could change anytime.
The second will be a matter of making the animation appear smooth enough for your user not to notice. It's not entirely a matter of behaving perfect, just appearing appropriately.
I would personally recommend an animation of the the button disappearing (animate it's alpha to 0) and reappearing based on if your view controller that goes over the tab bar is appearing or disappearing.
The animation for a navigation is (I believe) 0.3 seconds. If the button is in the middle of the tab bar, you'll likely want it invisible as the animating in view controller reaches it (if not sooner) so something between 0.1 and 0.15 seconds could be used to animate it out.
Now this does not make the button behave exactly the same as the tab bar, but with the quickness of the transition being so short, it will be unnoticeable really to the user.
Now just to provide a question for you to ask yourself. Why do you need to push a view controller that overlaps the tab bar? Why is that more desirable/necessary than presenting a modal view controller? If you can strongly argue for it, keep at it and good luck, if it's not necessary however, you may be able to achieve the experience you want with a modal view controller.
Check this one to put a button on the UITabBar. See if it works after with hidesBottoBarWhenPushed.
Edit: just to be clearer on what I am looking to do. I have 1 view with button on it. When you press the button a new view transisions in with a flip. On the new view their are two switched that I set through code after the user has clicked the button. What I want to happen is that the switches are in their final spots, before the new view flips in. What happens is the new view flips in, and then the UIswitches flicker into place.
This is the code I have. I have tried setting the uiswitch on viewwillappear and viewdidload, but each time it comes over with the default setting from IB and switched after the UIview transition is complete. I want the switch to be set already, so that once the view "flip" is done, there is no more movement on the screen. Thanks.
//set the uiswitch before the transision
[self.settingsPage.myUISwitchThing setOn:NO animated:NO];
//transition by flip
[UIView transitionFromView:self.view toView:self.settingsPage.view duration:1.0 options:UIViewAnimationOptionTransitionFlipFromRight completion:^(BOOL done ) {
[self.view removeFromSuperview];
Looks like the issue was that I was trying to animate the switch movement when I was setting the switch value in the viewdidload. setting animated:NO has resolved the issue in the iPhone simulator. hopefully it will fix it on the device when I can test it at home later.
I create a new tabbed application project in Xcode 4.2 using Storyboards.
In viewDidLoad, I add the following code:
[UIView animateWithDuration:30
delay:0
options:UIViewAnimationOptionRepeat | UIViewAnimationOptionCurveLinear
animations:^(void) {
CGRect imageViewFrame = self.scrollingImageView.frame;
imageViewFrame.origin.x = CGRectGetWidth(imageViewFrame) / -2;
self.scrollingImageView.frame = imageViewFrame;
} completion:nil];
Then I create the associated UIImageView property and wire it up in IB.
#property (nonatomic, strong) IBOutlet UIImageView *scrollingImageView;
I put an image into the imageview, run it in the simulator or my iPod Touch, and I see scrolling.
However, when I select the second tab and then go back to the first tab, the animation completes what appears to be immediately and I cannot get it to restart, even if I put the above into viewWillAppear. I have searched through lots of answers and cannot solve it.
Any help would be appreciated.
It appears that the issue you are dealing with is specific to tabbed bar controllers, not storyboards or the specific animation. The issue is that when you switch to a different tab, the animation stops, and when you return to the first tab, it doesn't resume.
Ordering the animation again in viewWillAppear does not work (as you mentioned), but if you first remove the animation in viewWillDisappear, then ordering it again in viewWillAppear should work. For example
- (void)viewWillDisappear:(BOOL)animated
{
[self.view.layer removeAllAnimations]; // or whatever you need to use to remove your specific animation
}
NB: The animation removal code should be in viewWillDisappear rather than in viewWillUnload, since viewWillUnload does not get called when you switch tabs.
So I created a glass pane or a custom UIView to handle touches. This glass pane sits on top of other views such as dummy UIButtons. When I set the alpha to be 0, the touches actually get intercepted by the views underneath the glass view. This is wrong. However, when I set the alpha to a low value like 0.2, the glass pane intercepts the touches.
The alpha setting was done in Interface Builder.
Anybody know how to set to the alpha to 0 and still get have this glass pane intercept touches?
Yes, it is standard behaviour.
For example, you can just set clear background of that UIView:
UIView *touchHandlerView;
touchHandlerView.backgroundColor = [UIColor clearColor];
In such case user wouldn't see that view - I assume that you want to do exactly that?
Yes, alpha=0.0f; and hidden=YES; have the same effect. This is very useful, because you can animate a fade-out and not have to worry about touches on the invisible object - ie you can say:
-(void)hideOverlayButton
{
[UIView beginAnimations:#"hideOverlayButton" context:nil];
[UIView setAnimationDuration:0.2];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[self.overlayButton setAlpha:0.0];
[UIVIew commitAnimations];
}
Then, when the animation is complete, the button won't respond to touches - there's no need to worry about deactivating it.
If what you want is to have invisible buttons, put a UIButton on the view, make sure it's at the front (bottom of the list in interface builder), set it's type to custom; don't set an image, background image or title. By default in interface builder you'll get alpha of 1 and a clear color.Then you can wire-up the IBOutlets in the usual way.