REFrostedViewController and iOS 8 - objective-c

I'm not sure if anyone has a fix for this but I've been trying to use this library I have everything setup but can't seem to achieve the blur like in the demo. I have navigation setup and working correctly but I cannot set a blur or blur tint color. I'm able to customize direction and a couple other properties but the blur does not seem to be working. The only thing I can think of is that this does not work for iOS 8. Here is my RootViewController's awakeFromNib:
- (void)awakeFromNib {
self.contentViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"homeController"];
self.menuViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"sideMenuController"];
self.liveBlur = NO;
self.liveBlurBackgroundStyle = REFrostedViewControllerLiveBackgroundStyleLight;
self.blurRadius = 60;
self.blurTintColor = [UIColor colorWithRed:45/255.0 green:55/255.0 blue:56/255.0 alpha:0.6];
}

If you need just iOS8 blur you can use this code. There you are creating VisualEffectView with blur effect and then set frame to this view.
UIVisualEffect *effect;
effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
// effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
// effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:effect];
blurEffectView.frame = self.view.frame;
[self.view addSubview:self.blurEffectView];
But you can also use UIImage+ImageEffects apples library for that case.
UPDATE
That's a result: blur on view controller and effected UILabel on top.

Related

iOS 8.0.2 : UIView frame animation not working when UINavigationController contained inside RootViewController

I've created a RootViewController / RootView that:
Handles the content layout for the app
Exposes and interface for performing application level behaviors, like presenting the "hamburger" menu or overlay views with CAKeyframe animations.
This is in accordance with good practice.
The Problem:
When the main content view presents a form, there's a utility to animate the frame of that view, when a field is selected that would otherwise be obscured by the keyboard. This has been working fine all the way up until iOS 8.0.2
On iOS 8.0.2 the frame for the form will no longer animate if you set a negative value for origin.y. Instead of going from the current origin.y to the required origin.y it jerks down by the amount it was supposed to move, then animates back to 0.
If I present the form outside of the RootVC it works correctly.
What I've tried:
Checked that RootView is not doing anything in layout subviews to prevent the animation. (In iOS8.0 it was. I removed this and problem was solved. Only to return in iOS8.0.2)
Checked the BeginFromCurrentState flags.
Instead of animating the form view, animate [UIScreen mainScreen].keyWindow. Works but causes some other side effects that I don't want.
Question:
What has changed with animation of UIViewControllers that are contained in another view in iOS8.0.2. It seems to be something very fundamental.
The code that animates frame to move input fields out the keyboard's way:
Looks something like this:
- (void)scrollToAccommodateField:(UIView *)view
{
UIView *rootView = [UIApplication sharedApplication].keyWindow.rootViewController.view;
CGPoint position = [view convertPoint:view.bounds.origin toView:rootView];
CGFloat y = position.y;
CGFloat scrollAmount = 0;
CGFloat margin = 25;
CGSize screenSize = [self screenSizeWithOrientation:[UIApplication sharedApplication].statusBarOrientation];
CGSize accessorySize = CGSizeMake(_view.width, 44);
CGFloat maxVisibleY = screenSize.height - [self keyboardSize].height - accessorySize.height - margin;
if (y > maxVisibleY)
{
scrollAmount = maxVisibleY - y;
CGFloat scrollDelta = scrollAmount - _currentScrollAmount;
_currentScrollAmount = scrollAmount;
[self scrollByAmount:scrollDelta];
}
else
{
if (_currentScrollAmount != 0)
{
_currentScrollAmount = 0;
[UIView transitionWithView:_view duration:0.30
options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseOut animations:^
{
_view.frame = [_view bounds];
} completion:nil];
}
}
}
Update:
I've since installed TPKeyboardAvoiding pod and its working very well. . leaving this open, in case its of interest to others.

How to get rid of the space on the left side of a custom UINavigationItem with a UISearchBar

In my navigation bar, I have a magnifying glass icon that brings up a search bar. I'm not using a UISearchDisplayController, so I opted to build my own UINavigationItem and then push it over the standard UINavigationItem using pushNavigationItem.
The problem is that the UINavigationItem seems to be pushed around 8 pixels to the right. This causes the cancel button (with localized text 'Annuleren') to be really close to the edge of the screen.
I tried inspecting the self.mySearchBar.bounds at runtime, but the origin is 0,0. I've played around a bit with AutoLayout and programmatically added constraints, but I haven't been successful. I hope it's possible without AutoLayout.
This is my code:
- (IBAction)displaySearchBar:(id)sender {
if (!self.mySearchNavigationItem)
{
self.mySearchNavigationItem = [[UINavigationItem alloc] initWithTitle:#""];
self.mySearchNavigationItem.hidesBackButton = YES;
self.mySearchBar = [[UISearchBar alloc] initWithFrame:CGRectZero];
self.mySearchBar.showsCancelButton = YES;
self.mySearchBar.delegate = self;
[self.mySearchBar sizeToFit];
[self.mySearchBar setPlaceholder:#"Zoeken..."];
UIView *barWrapper = [[UIView alloc]initWithFrame:self.mySearchBar.bounds];
[barWrapper addSubview:self.mySearchBar];
self.mySearchNavigationItem.leftBarButtonItem = nil;
self.mySearchNavigationItem.backBarButtonItem = nil;
self.mySearchNavigationItem.titleView = barWrapper;
UIButton *cancelButton;
UIView *topView = self.mySearchBar.subviews[0];
for (UIView *subView in topView.subviews) {
if ([subView isKindOfClass:NSClassFromString(#"UINavigationButton")]) {
cancelButton = (UIButton*)subView;
}
}
if (cancelButton) {
[cancelButton setTitle:#"Annuleren" forState:UIControlStateNormal];
}
}
[self.navigationController.navigationBar pushNavigationItem:self.mySearchNavigationItem animated:YES];
NSTimeInterval delay;
if (self.tableView.contentOffset.y >1000) delay = 0.4;
else delay = 0.1;
[self performSelector:#selector(activateSearch) withObject:nil afterDelay:delay];
}
try:
self.navigationController.navigationBar.barTintColor = self.mySearchBar.barTintColor;
if that doesn't work, you can add an underlay view to the navigation controller that is the color you would like. this may be useful: Get the right color in iOS7 translucent navigation bar
After searching for many hours, I gave up and went for a dirty fix. I'll leave it open for a while, in case someone knows why my searchbar is moved 8 pixels to the right.
Right before showing the UINavigationItem, I move the whole UINavigationBar to x-coordinate -8.
self.navigationController.navigationBar.frame = CGRectMake(-8.0, self.navigationController.navigationBar.frame.origin.y, self.navigationController.navigationBar.frame.size.width, self.navigationController.navigationBar.frame.size.height);
[self.navigationController.navigationBar pushNavigationItem:self.mySearchNavigationItem animated:YES];
And then on the cancel button click, I move it back to x-coordinate 0.
- (IBAction)cancelSearchBar:(id)sender {
[self.navigationController.navigationBar popNavigationItemAnimated:YES];
self.navigationController.navigationBar.frame = CGRectMake(0.0, self.navigationController.navigationBar.frame.origin.y, self.navigationController.navigationBar.frame.size.width, self.navigationController.navigationBar.frame.size.height);
}

UIScrollView metro theme

I am attempting to create a "metro" styled UIScrollView. It is similar to how iTunes app handles panels in the new ios version which wont be named.
I can't figure out how to have my views layout/scroll so that the next view in the sequence shows up. I've tried all sorts of things like keeping the contentSize the screen width but moving each view over -10ish so it will show up like above. I've tried making scrollView whose bounds were smaller than the screen so it would show the part of the next view. Nothing works.
Here is diagram of what I'm trying to do:
It seems extremely trivial on paper but I can't seem to get it work.
I'm not sure if I'm misinterpreting your requirements - but this might be a starting point to see how you could set it up:
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect viewBounds = self.view.bounds;
CGRect scrollViewFrame = CGRectMake(0, 0, floorf(CGRectGetWidth(viewBounds) / 2.2), CGRectGetHeight(viewBounds));
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:scrollViewFrame];
scrollView.center = self.view.center;
scrollView.contentSize = CGSizeMake(CGRectGetWidth(viewBounds) * 3, CGRectGetHeight(viewBounds) * 3);
scrollView.pagingEnabled = YES;
scrollView.clipsToBounds = NO;
UIPanGestureRecognizer *gestureRecognizer = scrollView.panGestureRecognizer;
[self.view addGestureRecognizer:gestureRecognizer];
for (int i = 0; i < 3; i++) {
CGRect frame = CGRectMake(10.f + (i * CGRectGetWidth(scrollView.bounds)), 10.f, CGRectGetWidth(scrollView.bounds) - 20.f, (CGRectGetHeight(scrollViewFrame) * 3) - 20.f);
UIView *view = [[UIView alloc] initWithFrame:frame];
view.backgroundColor = [UIColor redColor];
[scrollView addSubview:view];
}
[self.view addSubview:scrollView];
}
Literally just put this in an empty viewController's viewDidLoad:
The key things to note are
contentSize needs to be wide enough for all the panels
clipsToBounds should be NO so you can see the additional views
The bounds of the scrollview is essentially the main view port
pagingEnabled should be set
I've grabbed the panGestureRecognizer from the scrollview and attached it to the containing view instead so that panning is detected in the bounds of the containing view (which is larger) otherwise you are restricted to only detecting scrolls within the scrollviews bounds

Activity indicator not in center of the subview (which is not same size as parentview)

I am trying to center a spinner in the middle of the page using the code below.
self.aSpinner.center = self.view.center;
However when when I run the program, the spinner does not seem to be in the center
Is there any way to fix this?
EDIT:
I found the problem. It's not that the spinner is not in the center, but instead the subview has different bounds than its superview.
I am doing something like this in my code:
self.navcon = [[UINavigationController alloc]init];
self.photoViewTable = [[PhotoTableViewController alloc]init];
self.loadingPage = [[LoadingPageViewController alloc]init];
[self.photoViewTable.view addSubview:loadingPage.view];
[navcon pushViewController:photoViewTable animated:NO];
[self.window addSubview:navcon.view];
How can I set the size of loadingPage view to be equal to the parent view?
[spinner setCenter:CGPointMake(kScreenWidth/2.0, kScreenHeight/2.0)];
Setting the center properties might not be enough. In case your frame is being resize i will also set the autoresize mask of the spinner view:
spinner.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleBottomMargin);
spinner.center = CGPointMake(CGRectGetWidth(self.view.bounds)/2, CGRectGetHeight(self.view.bounds)/2);
Try do it on ViewDidAppear, there is correct self.bounds of view
I don't check self.center.
self.aSpinner.center = CGPointMake(self.view.bounds.width/2.0, self.view.bounds.width/2.0)
Work correct!
Check self has view or self is view

autoresize of uiview

I have a UIView in a UITabController.
And there is a UITableView in it.
When toggling in call status bar it doesn't do anything and the view is not automatically resized.
It assumes the right size based on whether the in call UIStatusBar was toggled when the app starts but if the UIStatusBar is toggled whilst the app is running nothing changes.
Another tab view with a UINavigationController seems to resize fine.
Here is the code
if ([indexPath indexAtPosition:0] == 0 || [indexPath indexAtPosition:0] == 1) {
if (!airportChooser) {
airportChooser = [[AirportChooserController alloc] init];
airportChooser.targetController = self;
airportChooser.view.autoresizesSubviews = YES;
airportChooser.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
[airportChooser.view setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth];
}
airportChooser.target = [indexPath indexAtPosition:0];
[self.parentViewController.parentViewController.view addSubview:airportChooser.view];
self.parentViewController.parentViewController.view.autoresizesSubviews = YES;
self.parentViewController.parentViewController.view.contentMode = UIViewContentModeRedraw;
[self.parentViewController.parentViewController.view setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth];
airportChooser.view.contentMode = UIViewContentModeRedraw;
//[airportChooser open];
}
Did you set the resizing mask of the UIView correctly? You can set it in Interface Builder in the size tab, it's the red lines that you can click.
You can also set it in code using something like:
[view setAutoresizingMask:UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight];
Also make sure the superview has set autoresizesSubviews to YES.
You can find more information about this in the UIView documentation.
Whilst klaaspeiter's answer makes sense and in some cases may be the right answer
in my specific case it was because I was adding a sub view to a UINavigationController's view with addSubview instead of pushViewController:view animated:NO;