UIToolBar lose translucent when clipsToBounds in iOS7.x - ios

Usually i use UIToolBar to fake the live blur effect, it has been working great for me. But there is a place I need to have a rounded corner toolbar, however, whenever I set the cornerRadius and clipsToBounds, the translucent (blur) effect is gone, my tool bar becomes transparent.
here is my code:
UIToolbar *blurView = [[UIToolbar alloc] initWithFrame:self.bounds];
blurView.barStyle = UIBarStyleBlack;
blurView.layer.cornerRadius = self.height / 2;
blurView.clipsToBounds = YES;
[self insertSubview:blurView atIndex:0];
here is a screen shot when clipsToBounds = YES, the corner is rounded, but the blur is gone.
But if i comment clipsToBounds out, the blur effect is back, but the corner is not rounded anymore.
The even stranger part is this issue only happens in iOS7.x, everything works perfectly in iOS8.x with the exactly same codes.
just in case if you wondering, here is how it looks on iOS8.x and how it should look on iOS7.x
I have been searching around on Stackoverflow and Google, can't find any clue. Please Help!

Try blurView.layer.cornerRadius = self.height / 2 - 0.5;

Related

Why is there a rough black edge when rounding corner of UIButton?

I'm adding a UIButton (with background image) to the navigation bar and setting rounded corners with a border. I'm getting a strange black outline on the corners:
Here's the code I'm using to create the button from viewDidLoad:
ProfileImageService *profileImageService = [ProfileImageService getService];
CGRect frame = CGRectMake(0, 0, 32, 32);
UIButton *button = [[UIButton alloc] initWithFrame:frame];
[button setBackgroundImage:profileImageService.profileImage forState:UIControlStateNormal];
[button addTarget:self action:#selector(showMenu) forControlEvents:UIControlEventTouchUpInside];
button.layer.cornerRadius = button.frame.size.height / 2.0;
button.layer.masksToBounds = YES;
button.clipsToBounds = YES;
button.layer.borderWidth = 3;
button.layer.borderColor = [UIColor colorWithRed:0 green:0.67 blue:0.97 alpha:1].CGColor;
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
How can I make the border smooth and get rid of the subtle black outline?
What you're seeing is your profile image (the person's face) bleeding through the edge. This is because the border is anti-aliased and so has small amounts of transparency through which the profile image can bleed.
Since you're clipping the profile image and the border together, there's nothing stopping the profile image from extending through the border. (i.e. clipsToBounds won't clip the content to the inside of the border; it clips everything to the outside of the border) You can prove this by using a bright red image: you'll see a bright red fringe.
If you can just make the profile image circular and the right size beforehand (either offline or in code) then you'll avoid this problem.
The other solutions I see are to either implement your own drawRect: method and do the drawing yourself or to create another sub-layer of the button to hold the image which is clipped in the same way, but without the border. (Either way, you probably need to make your own UIControl for this rather than using UIButton, as manipulating the button's layers could lead to weird behavior.)
Edit: Here are some other solutions, too: iOS: Rounded rectangle with border bleeds color

UIProgressView track and progress images not working in iOS7

I have a UIProgressView that has been customised with a progress and track image. I also customised the size of the progress view. This works fine in iOS 6. I am facing problems getting this to work in iOS7.
_progress.progressViewStyle = UIProgressViewStyleBar;
_progress.trackImage = [UIImage imageNamed:#"summary-progress-track.png"];
_progress.progressImage = [UIImage imageNamed:#"summary-progress.png"];
_progress.frame = CGRectMake(50, 50, 100, 10);
Not only is the height being ignored but the custom images do not get applied. I just get a blue tinted progress bar like this:
I think the default tint colour is somehow overriding the progress images. I have also tried setting this with UIAppearance but it did not work.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIProgressView appearance] setProgressImage:[UIImage imageNamed:#"summary-progress.png"]];
[[UIProgressView appearance] setTrackImage:[UIImage imageNamed:#"summary-progress-track.png"]];
return YES;
}
Personally I use the MPProgressHUD for all progress tracking on a view. Here's the link to the download
https://github.com/jdg/MBProgressHUD
The usage is as simple as it get. Here's a tutorial you might like to check out.
http://code.tutsplus.com/tutorials/ios-sdk-uiactivityindicatorview-and-mbprogresshud--mobile-10530
The MPProgressHUD has a specific method to show custom images.
This should be helpful if you have not already seen this.
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/UIKitUICatalog/UIProgressView.html#//apple_ref/doc/uid/TP40012857-UIProgressView-SW1
the blue color is the default tint color for the control in iOS7 that gets applied.
Found a solution. If anyone else is stuck on this check out this answer and suggested code to workaround the issue: UIProgressView custom track and progress images in iOS 7.1
I print the progress's subviews and find that one of them's frame width is 0,
so after
[_videoProgressView setProgress:progress animated:NO];
reset the track and progress images
UIImageView *trackImageView = _videoProgressView.subviews.firstObject;
UIImageView *progressImageView = _videoProgressView.subviews.lastObject;
CGRect trackProgressFrame = trackImageView.frame;
trackProgressFrame.size.height = _videoProgressView.frame.size.height;
trackImageView.frame = trackProgressFrame;
progressImageView.frame = trackProgressFrame;
progressImageView.image = progressImage;
trackImageView.image = trackImage;

Bar translucency gone in iOS 7.0.3

Compare the two screenshots:
Done on iOS 7.0 simulator
And the one done on iOS 7.0.3 iPhone 4S:
Same code here and there and same stuff! Any idea why the translucency is gone on the real device?
I have this code to simulate it (I know it's probably awkward and not right but that's how it is):
topMenuView = [[UIView alloc] initWithFrame:CGRectMake(self.view.frame.origin.x, 0, self.view.frame.size.width, TOP_BAR_ORIG_HEIGHT)];
topMenuView.clipsToBounds = YES;
UIToolbar *topMenuViewBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, -4, self.view.frame.size.width, TOP_BAR_ORIG_HEIGHT + 4)];
topMenuViewBar.barStyle = UIBarStyleDefault;
topMenuViewBar.barTintColor = [BSFunctions getColorFromHex:#"1ea6ff"];
const CGFloat statusBarHeight = 20;
UIView *underlayView = [[UIView alloc] initWithFrame:CGRectMake(0, -statusBarHeight, topMenuViewBar.frame.size.width, topMenuViewBar.frame.size.height + statusBarHeight)];
[underlayView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
[underlayView setBackgroundColor:[BSFunctions getColorFromHex:#"1ea6ff"]];
[underlayView setAlpha:0.36f];
[topMenuViewBar insertSubview:underlayView atIndex:1];
UIView *underlayView2 = [[UIView alloc] initWithFrame:CGRectMake(0, -statusBarHeight, topMenuViewBar.frame.size.width, topMenuViewBar.frame.size.height + statusBarHeight)];
[underlayView2 setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
[underlayView2 setBackgroundColor:[BSFunctions getColorFromHex:#"0291ff"]];
[underlayView2 setAlpha:0.36f];
[topMenuViewBar insertSubview:underlayView2 atIndex:2];
[topMenuView addSubview:topMenuViewBar];
[self.view addSubview:topMenuView];
The main point is it used to work before on the device! But after iOS 7.0.3 came out it changed. I'm noticing the same behavior in Facebook and Fitocracy iOS apps.
UPDATE
On Xcode 5.0.1 with iOS 7.0.3 simulator we have this (which is different from the first image on iOS 7.0 simulator as you can see):
OK, so after having played around with the colours a bit more, I managed to get a similar sort of appearance with the blur!
Previously, I was setting a barTintColor on the navigation bar appearance which had the following values:
R:17
G:63
B:95
A:1
This was fine in iOS < 7.0.3, and the output color in the nav bar (with the blur effect) was actually:
R:62
G:89
B:109
Since iOS 7.0.3, the barTintColor seems to take into account the alpha value of the color we set. This meant that the nav bar was actually outputting a solid color 17,63,95, and there was no blur effect.
The key to getting the blur effect back is setting an alpha < 1 in the barTintColor.
After lots of guess work and trying different RGB values, I managed to get the exact same RGB output from the nav (and tab) bar, using the following RGBA:
R:4.5
G:61.6
B:98
A:0.65
It does not look like there's a magic ratio to apply to the previous color to obtain the new one.
Anyway I've actually rejected the binary that got approved this afternoon, and have re-submitted with these new values so that user's don't get an ugly app :)
Hope this helps.

UIImageView image not retained during drawRect event in iOS7

I am transitioning an app project from iOS-6.1 and xcode4 to iOS-7 and xcode5. My original iOS-6.1 routine to draw on a transparent UIView above an UIImageView does not work in iOS7. Here is what I have done and how I have fixed it. I'm hoping someone can tell me how to do it better!
Using InterfaceBuilder, I create a square (320 x 320) UIImageView on my View Controller view. I then make a 320 x 320 UIView directly above it and use Interface Builder Attributes Inspector to make it transparent.
Then I link up the setters and getters in Interface Builder. The UIImageView #property is (nonatomic, retain). I then subclass the now-transparent UIView and do my drawing in drawRect.
In iOS6.1 this works just fine. In iOS-7 I have a problem.
(Several, actually). As a side note, in xcode5 I cannot get the Attributes Inspector to appear when I select the UIView, when I try to make the UIView transparent. Could this be a bug, perhaps in my installation of xcode5, or is the xcode5 Attributes Inspector no longer supporting UIViews?
So I make the UIView transparent programmatically in iOS-7. I'm doing it here in the UIView's drawRect, which is probably overkill, but I'm still trying to figure out what's going on:
self.backgroundColor = [UIColor clearColor];
self.opaque= NO;
self.window.backgroundColor = [UIColor clearColor];
and then I have to make the UIImageView appear, also in drawRect, using this code
UIImage *myImage = [UIImage imageNamed:#"myImage.png"];
CGRect imageRect;
imageRect.origin.x = self.bounds.origin.x + 10;
imageRect.origin.y = self.bounds.origin.y + 10;
imageRect.size.width = 300;
imageRect.size.height = 300;
[myImage drawInRect:imageRect];
And things are now fine. I get what I want which is my drawing on top of the image. But, it seems like a terrible performance hit to be calling myImage every time drawRect needs to be called.
Can anybody see why my original method of displaying the UIImageView once does not work in iOS-7? Has anybody a better solution to my expensive show-the-image-every-time method?
Thanks in advance
TFR

Applying rounded corners for the whole application

How can I implement rounded corners applied to the whole view as seen on screenshot (note that both navigation bar and keyboard corners are rounded)?
I've tried setting cornerRadius = 10 and masksToBounds = YES for both window.layer and window.rootViewController.view.layer, but only the bottom view corners are getting rounded, the navigation bar still stays square.
Update.
Setting cornerRadius to a window.layer actually adds rounded corners to the top too, but those corners are not visible under the status bar unless cornerRadius is greater then 20.
Ok, I've asked Andrew Stone, a developer of Twittelator Neue, on Twitter, and here's his recipe, published with Andrew's permission:
We're going to write a book on coding tricks in Neue! We overlay a window w an image containing 4 corners over everything
We also have a custom nav bar with a stretchable image w/ tops rounded
So here's how I did it in my own project:
UIImage *overlayImg = [UIImage imageNamed:#"overlay.png"];
CALayer *overlay = [CALayer layer];
overlay.frame = CGRectMake(0, 0, overlayImg.size.width, overlayImg.size.height);
overlay.contents = (id)overlayImg.CGImage;
overlay.zPosition = 1;
[self.window.layer addSublayer:overlay];
overlay.png is a transparent fullscreen image with black corners.
They're probably using a background image on the navigation bar that includes the rounded corners.
iHunter's answer works great for me except when I try to use the TWTweetComposeViewController, that shows the keyboard but not the tweet view. Then I should to make the overlay as a property in the AppDelegate.h and before tweetView, remove the overlay. At tweet done, turn add overlay again.
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[delegate.overlay removeFromSuperlayer];
TWTweetComposeViewController *tweetSheet = [[TWTweetComposeViewController alloc] init];
tweetSheet.completionHandler = ^(TWTweetComposeViewControllerResult result) {
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[delegate.window.layer addSublayer:delegate.overlay];
};
[self presentModalViewController:tweetSheet animated:YES];
I doubt that the window has rounded corners because I don't believe the status bar has a height greater than 20 units. I suspect that the window is simply set with a black background (or whatever color is needed to match the status bar, and then another view is place on top. That view on top has the rounded corners. similarly, any other subviews will have rounded corners to help with this illusion.

Resources