I am creating a UITableViewController (at the root of a UINavigationController) and presenting this modally on top of another view controller. I have it working to an extent, such that when the view loads and viewDidAppear is called, the visual effect looks good. But right after viewDidAppear, the visual effect goes away and the tableview has a white background.
In my presented UITableViewController, I added this in viewDidLoad:
if (NSClassFromString(#"UIVisualEffectView") && !UIAccessibilityIsReduceTransparencyEnabled()) {
self.tableView.backgroundColor = [UIColor clearColor];
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
[blurEffectView setFrame:self.tableView.frame];
self.blurView = blurEffectView;
self.tableView.backgroundView = self.blurView;
}
I also implement this, to make sure the cells have a clear background:
- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
if (NSClassFromString(#"UIVisualEffectView") ) {
cell.backgroundColor = [UIColor clearColor];
}
}
I also set the cell.backgroundColor = [UIColor clearColor] in tableView's cellForRowAtIndexPath: but that doesn't help either.
Again, I get the correct effect when the view loads, but it loses the blur background as soon as it appears on screen. Any ideas what might be going wrong? I have also tried to retain the blueEffectView as a property in my view controller, but no luck
Are you using Storyboards?
Select the view controller that's used modally (or if it's wrapped in another VC, select the wrapper) and set the Presentation combo box to "Over Full Screen" or "Over Current Context". (I don't actually know what the difference is, they both seem to do the same thing.)
After doing that, your blur effect should Just Workâ˘. Also, I think this is new in iOS 8, I haven't tested this in iOS 7 yet.
The problem is, when you present a view controller modally with the default settings, once it has finished taking over the screen, the underlying view controller seems to be essentially erased. This is why your blur effect looks great until the presentation animation completes - the underlying view vanishes.
To implement the desired behavior, you'll need to change the segue presentation style to something that will preserve the underlying view controller, like Over Full Screen instead of the default Full Screen.
Note that when you dismiss this modal presentation, viewDidAppear will not be called on the presenting view controller, because it's now always visible. That can bite you if you were relying on that method to perform any function upon dismissal.
Related
I use UIVisualEffectView as my tableview's backgroundView, just for the blur effect, everything is fine except when I begin to swipe the current view back to previous view, the tableview's background immediately become black, not blurred anymore.
UIVisualEffectView is actually a hack in the Apple framework. It's not an overlapping layer, it completely replaces the layers behind itself by processing them. Try to add this effect behind the table and clear background of table view.
In viewDidLoad method
self.tabelView.backgroundColor = [UIColor clearColor];
In cellForRowAtIndexPath method
cell.backgroundColor = [UIColor clearColor];
I'm working on an app that will rely on one main view controller with a row of buttons at the bottom to display other views with information. From one of these buttons I want to present a tableview that presents a list of song titles. This app plays sound files, and I want the user to be able to tap a button, then select a song to be the default song to play. I want to present this tableview with a uiview animation, and I want it to be semi-transparent and only fill a portion of the screen. I've tried creating a UITableViewController and then presenting it from the main view controller like so:
UITableViewController *tableView = [[UITableViewController alloc]init];
[self presentViewController:tableView animated:YES completion:nil];
This presents a view controller that fills the entire screen though, which is not what I want. And changing the view controller's frame at instantiation time doesn't seem to have an effect. I can just animate a UITableView into the main view controller's view, but then I'm not so sure who is supposed to be the delegate and data source. Any suggestions? Thanks in advance.
While adding table view as a subview, u can set its frame size or bound, and display it with animation whatever you like. Yes, you can set delegate and datasource to self while adding .
I use: (in viewDidLoad)
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.opaque = NO;
Then in cellForRowAtIndexPath:
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
cell.backgroundColor = [UIColor colorWithWhite:1 alpha:.55];
Not sure if this is what you wanted, but it gives you the option to make everything clear. (obviously the alpha would change for your case, but that measures the opacity of the cells)
I am pushing a view controller via:
[self.navigationController pushViewController:[[UIViewController alloc] init] animated:YES];
But the animation lags/pauses a for half a second mid way through. The animation is not complete. Here's the gif;
With out more detail I can think of 2 possible problem with that.
Is there Shadow added in code to the view that will be covered by the new ViewController. If it is the case, use ShadowPath or an translucent view instead (the property Shadow is expensive while animating, been there done that)
Is the backgroundColor of new ViewController "clearColor" ? I've seen strange rendering problem with that kind of thing.
Try:
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = [UIColor whiteColor];
[self.navigationController pushViewController:vc animated:YES];
That is the 2 possible problems I can think of the top of my head with so few detail.
Never rely on the default background color, it has change with iOS version and is not consistant across controls and can even be different if the view is created in code or from a Xib (in the same iOS version).
In app delegate, set your window's background color to white.
window?.backgroundColor = .white
Also in the the pushed view controller, set its view to white.
view.backgroundColor = .white
I experienced the same issue when programmatically embedding my view controller in a UINavigationController.
While setting the background color as suggested by VinceBurn solved the pausing, it made the entire animation white, fading in the actual content only when the animation finished.
For me the problem was solved by making sure the content was correctly sized in -viewDidLoad.
I have a bunch of animations set to repeat that work beautifully if they're in their own view controller that is pushed to, but if I modally present them (via a modal segue from a UIButton tap) suddenly none of them play.
Does anyone have any idea why this may be?
This is an example of one animation being added:
UIView *topTapRipple1 = [[UIView alloc] initWithFrame:(CGRectMake(73, 30, 13.0, 13.0))];
topTapRipple1.backgroundColor = [UIColor clearColor];
topTapRipple1.layer.cornerRadius = topTapRipple1.bounds.size.height/2;
topTapRipple1.layer.borderColor = [UIColor colorWithRed:0.886 green:0.886 blue:0.886 alpha:1].CGColor;
topTapRipple1.layer.borderWidth = 1.0;
[self.middleContentView insertSubview:topTapRipple1 belowSubview:self.middle];
Where that's the view that is added in order to create the animation. But that view never even gets added. Why is this?
Here's an example project replicating the issue: https://dzwonsemrish7.cloudfront.net/items/163k0D2f2L2P3H0E3y2i/animationtest.zip
Since you are doing the animations in viewDidLoad, the segue animation isn't complete when you try to start them. Try putting the animations in viewDidAppear:
Edit: This kind of animation would ideally be done with CAAnimation and CALayer. Creating and adding all those subviews seems like overkill.
EDIT: I have Found the answer to my own question. Please look at the bottom of my post.
I am having an animation issue trying to push a UIViewController in didSelectRowAtIndexPath on a UITableView programmatically. When I run this code in iOS 6 it works fine. In iOS 7 the animation is messed up (it animates to the left about 20% of the screen then disappears). If I do this in storyboard the animation is fine. Am I missing something or is there a way around this without using storyboard?
// This is a cut down example.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIViewController *viewController = [[UIViewController alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
}
This is what it looks like right before the tableView disappears. I understand why it does this. Its because the new view being pushed should animate sliding in over it as it does when using storyboard. For some reason it does not work programmatically.
EDIT: This is all I missed
For some reason you have to set a backgroundColor.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIViewController *viewController = [[UIViewController alloc] init];
[viewController.view setBackgroundColor:[UIColor orangeColor]];
[self.navigationController pushViewController:viewController animated:YES];
}
This is the default "parallax" behavior triggered by the pushViewController:animated: method in iOS7.
Having little experience with storyboards I suspect that their segues are different from UINavigationController push/pop animations.
You can override the default push/pop by building custom animated or custom interactive transitions.
Or you could use the UIViewController method:
transitionFromViewController:toViewController:duration:options:animations:completion:
to customize this behavior. Hope this helps and hope I've understood your question...
I've been have similar problems which I managed to fix by delaying the call
[self performSelector:#selector(displayMyViewController) withObject:nil afterDelay:0.2f];
I have experienced this issue too. Another reason for this would be modifying the destination view's alpha. At least that's what i did.
If you want to change the view's opacity when you're displaying a loading HUD or something, don't modify the view's alpha.
Instead, adjust the alpha of the Table View or Collection view, or whatever you have in that view. If you have several elements, put them all in a view and change that view's alpha.
Another reason would also be the background color, as stated above. You need to set the background color of the destination view. I ran into this several times as well.