UIProgressView custom track and progress images in iOS 7.1 - ios

iOS 7.1 seems to have broken the custom image properties in UIProgressView. Code that used to successfully customize progress views now yields the default appearance.
I set up a sample project that does this in viewDidLoad:
self.progressView.frame = CGRectMake(self.progressView.frame.origin.x, self.progressView.frame.origin.y, self.progressView.frame.size.width, 9);
UIImage *img = [UIImage imageNamed:#"progress_bar_fill.png"];
img = [img resizableImageWithCapInsets:UIEdgeInsetsMake(0, 4, 0, 4)];
self.progressView.progressImage = img;
img = [UIImage imageNamed:#"progress_bar_empty.png"];
img = [img resizableImageWithCapInsets:UIEdgeInsetsMake(0, 4, 0, 4)];
self.progressView.trackImage = img;
I still get the default appearance. I've stepped through and verified that img is non-nil as expected. What's going on?
UPDATE: There is an OpenRadar for this, and I've also filed a radar of my own complete with a sample project.
UPDATE 2: As noted by Axy below, you have to add this to get the JEProgressView to work correctly:
_progressBar.tintColor = [UIColor clearColor];

This is very annoying. I didn't find a way to fix this without subclassing UIProgressView.
Anyway here's how I fixed this: https://gist.github.com/JohnEstropia/9482567
You will have to change occurrences of UIProgressView to JEProgressView, including those in NIBs and storyboards.
Basically, you'd need to force assigning the images directly to the UIProgressView's children UIImageViews.
The subclass is needed to override layoutSubviews, where you adjust the heights of the imageViews according to the image sizes.

You are correct. This bug has been present since 7.1 first made its appearance in Xcode 5.1 seed 1. I submitted (and resubmitted) the same bug for all 5 seeds of Xcode 5.1, and now on Xcode 5.1. But Apple did not fix it.
Please submit this bug too! You may refer to my bug if you like: 15547259. The more the better! I regard this as serious breakage, because it means that an app that was working fine is now broken (if it uses a progress view with a progressImage).

I used John Estropia solution, but it was showing the blu tint bar in overlay to mine, with quite a strange graphical effect.
I added
_progressBar.tintColor = [UIColor clearColor];
and It went just fine. Thanks for the solution man.

Hello friends I have used the following code to add UIProgressView in my app:
UIProgressView *progressView;
progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
progressView.progressTintColor[UIColor colorWithRed:187.0/255 green:160.0/255 blue:209.0/255 alpha:1.0];
[[progressView layer]setCornerRadius:10.0f];
[[progressView layer]setBorderWidth:2.0f];
[[progressView layer]setMasksToBounds:TRUE];
progressView.clipsToBounds = YES;
[[progressView layer]setFrame:CGRectMake(30, 295, 260, 25)];[[progressView layer]setBorderColor[UIColor whiteColor].CGColor];
progressView.trackTintColor = [UIColor clearColor];
[progressView setProgress: (float)count/15 animated:YES];
Hope the code will be helpful to you, I found it here : Source of Code

I have tried to implement the JEProgressView files from John Estropia - but it doesn't work. I must have done something wrong - but I'm a little new to this. Can someone explain how exactly to do this? I know it might be a stupid question - but after a lot of googling I thought asking was the only way.

I'm also catched this bug. I tried to fix it playing with UIProgressView properties but without result. John's Estropia solution posted above, also don't work for me, maybe it's not support auto layout, so I made my own temporary solution for bypassing this bug. https://github.com/ninjaproger/AKProgressView

For me this worked for iOS version 7.1 and above for progress image:
if ([[UIDevice currentDevice] systemVersion] >= 7)
self.progressView.tintColor = [UIColor colorWithPatternImage:img];

With Xcode5 it is now possible to make resizable images with Interface Builder too. We can specify the resizing direction and content inset and select the area of to be strecthed right within the interface builder.
To avail this feature you have use Asset Catalog for the image you want to resize.

Related

UINavigationBar appearance background image duplicated and blurred in iOS 7.1

I have an interesting issue with an existing project and iOS7.1, I think. I've had code working and performing normally; since updating XCode and my iOS on my devices I have a problem, a transparent background image used in the Navigation Bar for that project is now rendered twice, once at the correct size and again blown up and blurry. The code only adds the image via the [UINavigationBar appearance] api in the app delegate. To check that this wasn't a specific bug with my code I create a default xcode project using the master detail default, set it to be iPhone only, added some newly created images and set them using the same calls in the app delegate. This project had the same issue and is on github here:
UINavigationBarBug github source
This is the relevant chunk of code imo:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"TLS.png"]
forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBarTintColor:RGB(233, 155, 20)];
[[UINavigationBar appearance] setTintColor:RGB(245, 245, 245)];
return YES;
}
A screenshot of the problem:
Looking at the transition documentation what i am doing here should be fine, the navigation bars at 44 points high should be scaled horizontally and not vertically. I'm also pretty sure this problem never occurred prior to the update (it would have been spotted by internal QA prior to uploading the code to apple for review).
Two things fix it:
1) Using non transparent images, if it still has the problem it is loading the 'correct' image second and due to the lack of transparency overriding the incorrectly rendered one.
2) Using a navigation bar that is 66 points high instead (available in the project with a top transparent section as TLS-ios7), changing the code in the app delegate to use that fixes the problem.
Can anyone enlighten me as to what is going on here? Is this a bug, is it my fault, is there some section of documentation that informs me why this is so?
Thanks!
** Update: I recently found an iPad lying around still running iOS 7.0, this problem does not occur. **
I had a similar issue on my app. I solved it by setting the "translucent" of my UINavigationBar to NO.
[self.navigationController.navigationBar setTranslucent:NO];
You can disable image stretching by defining left and top caps.
Here's a Swift 3 solution:
let navbarImage = image.stretchableImage(withLeftCapWidth: 1, topCapHeight: 1)
UINavigationBar.appearance().setBackgroundImage(navbarImage, for: .default)
Example before:
and after the fix:
I just received this following my bug report... tl;dr It's me providing an image with an incorrect height:
Workaround for iOS 7.1 is to specify a resizable image with a non-zero inset. Internally UINavigationBar will tile your image if it isn't quite the right size and that is basically what was happening here – since the image wasn't tall enough (the navigation bar is top attached, so the image needed to be 64pt tall not 44pt) it would get tiled. If you set it to stretch and configure the cap insets such that it only stretches pixels that are uniform you should be able to avoid this issue.
I had a similar looking issue and it turns out I didn't have the correct image assets in the assets catalog. I only had retina assets but when I imported, they went into the 1x box in the asset catalog - moving them to the 2x box fixed my nav bar for me.
I had a similar problem, I had a logo with transparent background. Height was fine. Added in coloured background and the problem stopped.

UIKeyboard not automatically translucent in iOS7

I understand that when developing in Xcode 5 with and iOS 7 project, the keyboard that pops up when interacting with a UITextField should be translucent and show through any colors in the background. This is not the case in both my projects. I have a colored & blurred background and I'm hoping for that to transpire through the keyboard; however the keyboard remains the default white/gray.
This is what I have so far as a demo:
UIColor *tintColor = [UIColor colorWithWhite:0.21 alpha:0.4];
UIColor *background = [[UIColor alloc] initWithPatternImage:[[UIImage imageNamed:#"universe.jpg"] applyBlurWithRadius:19
tintColor:tintColor
saturationDeltaFactor:1.8
maskImage:nil]];
self.view.backgroundColor = background;
UITextField *text = [[UITextField alloc] initWithFrame:CGRectMake(200, 200, 300, 60)];
[self.view addSubview:text];
I have even tried to set the keyboard appearance type to both UIKeyboardAppearanceDefault and UIKeyboardAppearanceLight
Can someone please guide/tell me on how can I achieve the keyboard translucent effect? Should this be automatic?
Thanks
EDIT 1:
I have the iPad mini, I have the iPad 3rd generation and the iPad 4th generation both with retina displays.
Running iOS 7.0.2
Your code, setup and example worked fine on my xCode. I tried first only setting the background color to something obvious like red.
self.view.backgroundColor = [UIColor redColor];
This showed through the keyboard. Afterwards I tried an image without a blur effect.
UIImageView* img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"images.jpeg"]];
img.frame = self.view.frame;
[self.view addSubview:img];
This to showed through, but not as much as the red because the image I used was one similar to a galaxy as you stated, and therefore had a lot of black in it.
Lastly I tried your exact code, using the gaussian blur effect to create a color.
UIColor *tintColor = [UIColor colorWithWhite:0.21 alpha:0.4];
UIColor *background = [[UIColor alloc] initWithPatternImage:[[UIImage imageNamed:#"images.jpeg"] applyBlurWithRadius:19 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil]];
self.view.backgroundColor = background;
This to also worked, but it was extreamly hard to notice. The combined affect of dark colors being blurred once by the gaussian and being blurred again by the keyboard made it almost unnoticeable. I suggest you try a similar approach to see if you are actually getting a transparent keyboard, because if the code and info you have given are correct, then it seems like you are and maybe can not see it.
Also the keyboard is only slightly transparent, so if you are expecting a full transparency then that is not the case. This slight transparency gets minimized the more uniform the background color is for instance if you had an all black or white background it would be unnoticeable.
Edit: I confirmed that this is not the case on the iPad running iOS7.0.x I get the standard all grey keyboard, even using standard apps like Safari. It seems that Apple had not optimized the transparency for such large screens and it was causing lag issues. It also seems that this is partially fixed in iOS7.1 and there are more transparent iPad features in iOS7.1, but people are recommending turning them off as they cause the iPad to run slower than normal.
iOS 7.0.3 reduced much of the translucency in navigation bars, toolbars, and the keyboard.
For navigation bars and toolbars, starting in iOS 7.0.3, you can adjust the alpha property of the UIColor set as barTintColor if you want it more translucent.
As far as public APIs go, keyboards in iOS 7, however, still have only these options:
textField.keyboardAppearance = UIKeyboardAppearanceDefault; // the default (same as light)
textField.keyboardAppearance = UIKeyboardAppearanceDark; // dark look (previously UIKeyboardAppearanceAlert)
textField.keyboardAppearance = UIKeyboardAppearanceLight; // light look
So I assume you're not getting the translucency you'd like because you're using iOS 7.0.3 or later. You can verify this by downloading an older version of Xcode and running your app in that version's simulator.
As far as private APIs, the keyboard background is made up of UIKBBackdropView and UIKBBackgroundView. You can take a look at their extracted header files here, but you should not modify these if you're submitting to the App Store. (These modifications are grounds for rejection, and also aren't documented so they could be changed in any iOS update.)
I built a simple app to test to try to find this issue, but I've been unable to replicate it except by setting IPHONEOS_DEPLOYMENT_TARGET to a lower version number like 6.0, then running on iOS 6.0. In all cases, on all iOS 7 devices and simulator, the default keyboard has a translucent blur of the content underneath it.
Perhaps you could share a picture, or a sample project?

Use iOS 6 Style Segmented Control in iOS 7?

Is it possible to have a segmented control on an iOS 7 device show up as the iOS 6 version of the control?
We really aren't ready for an interface redesign and the new flat control doesn't jive with the rest of our UI. It would definitely be best to keep the iOS 6 style for now, if possible.
To clarify, I am compiling using the iOS 6.1 Base SDK. I am aware that this is the "obvious" answer to my question, but it does not work. Most other UI elements will show up with iOS 6 styling by doing this, but like the UIAlertView and UIActionSheet, the UISegmentedControl does not. However, unlike the UIAlertView and UIActionSheet, UISegmentedControls do not feel like a "system" item; they should be able to display in iOS 6 mode.
Edit: I thought it would be helpful if I finally included a picture with this (probably should have done this from the start). However, the answer I provided did fix the issue. Also, in retrospect, it looks like this might be the iOS 6 style after all, it's just displaying so wrong that it appears like iOS 7 style.
I manage to do a pretty good job of solving this problem by setting all the attributes manually, but it is not quite perfect.
This is what I ended up doing:
- (void)fixSegmentedControlForiOS7
{
NSInteger deviceVersion = [[UIDevice currentDevice] systemVersion].integerValue;
if(deviceVersion < 7) // If this is not an iOS 7 device, we do not need to perform these customizations.
return;
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
[UIFont boldSystemFontOfSize:12], UITextAttributeFont,
[UIColor whiteColor], UITextAttributeTextColor,
nil];
[self.segmentedControl setTitleTextAttributes:attributes forState:UIControlStateNormal];
NSDictionary *highlightedAttributes = [NSDictionary dictionaryWithObject:[UIColor whiteColor] forKey:UITextAttributeTextColor];
[self.segmentedControl setTitleTextAttributes:highlightedAttributes forState:UIControlStateHighlighted];
self.segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
self.segmentedControl.tintColor = [UIColor colorWithRed:49.0 / 256.0 green:148.0 / 256.0 blue:208.0 / 256.0 alpha:1];
}
To fix images assigned with InterfaceBuilder use this code:
- (void)fixImagesOfSegmentedControlForiOS7
{
NSInteger deviceVersion = [[UIDevice currentDevice] systemVersion].integerValue;
if(deviceVersion < 7) // If this is not an iOS 7 device, we do not need to perform these customizations.
return;
for(int i=0;i<toSegmentedControl.numberOfSegments;i++)
{
UIImage* img = [toSegmentedControl imageForSegmentAtIndex:i];
UIImage* goodImg = [img imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
// clone image with different rendering mode
[toSegmentedControl setImage:goodImg forSegmentAtIndex:i];
}
}
I just ran into this problem today myself. The app I'm working on updating is quite old, and still uses xib files, so I do not know if this works on storyboards or not. As others suggested above, you still need to use the iOS 6.1 SDK, but this alone is not enough. After performing the following steps, I was able to get the old UISegmentedControl appearance back:
Open the interface builder document in question
Go to the file inspector (first inspector tab; has a document icon)
Under the "Interface Builder Document" section, change "Opens in" to Xcode 4.6
I do believe this is a bug, and I would not be surprised if there isn't a workaround for UISegmentedControl instances created in code. I'm guessing this is somewhat related to the deprecation of the segmentedControlStyle property in iOS 7 (see https://developer.apple.com/library/ios/documentation/uikit/reference/UISegmentedControl_Class/DeprecationAppendix/AppendixADeprecatedAPI.html#//apple_ref/occ/instp/UISegmentedControl/segmentedControlStyle).
Hope this helps someone out there.
If you save the iPhoneOS6.1.sdk file from the previous version of XCode and add it to Xcode 5 in the same path you can then build an app against the 6.1 SDK so that when it runs on 7 everything is like 6. Linking against iOS7 SDK tells iOS to make everything look like iOS7 if possible. Essentially then you have an iOS6 app but building it with XCode 5.
If you use images on any of your UISegmentedControl segments, you'll need to add some code to set those properly on iOS 7, otherwise they'll be used as a template image and the selected segment will be a cutout of the segment's background.
UISegmentedControl under iOS 7 interprets its images as being in rendering mode UIImageRenderingModeAlwaysTemplate unless otherwise specified. I had to use -[UIImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] on each segment's image for iOS 7 to achieve the previous behavior.
Either you could:
Not update your app at all for iOS7 until you're ready to make some UI changes. Apps compiled against the iOS6 SDK will run in iOS6 Compatibility mode on iOS7 and will look exactly the same as they did in iOS6.
Apply custom background, separator, etc images to your segmented controls that mimic the look they had in iOS6.
Yes, it is possible if you recreate the control by your own. Create a fake segmented control that looks like and work like one.
In my app, I have set the Segmented control to "Bar" style. It renders in ios6 style on my ios7 iphone5 (whoa, 5,6,7). However, the text inside the segments are cut and have the three dots "..." added, no matter how wide the view is.
So the ios6 segmented control rendering in ios7 seems really buggy
Is it possible? Not really...
You could make your own custom segmented control.
Or you could use the UIAppearance proxy to customise your segmented control with images but then it's your responsibility to make it look like it was on iOS 6.

Is customising UISearchField is private

I need to customise UISearchBar:
Change search text color
Change favicon
There is no API provided by Apple. However, this is one of possible solution:
for(UIView *subView in _searchBar.subviews){
if([subView isKindOfClass:UITextField.class]){
UITextField *searchField = (UITextField*)subView;
searchField.textColor = [UIColor darkGrayColor];
UIImage *image = [UIImage imageNamed: #"loop.png"];
UIImageView *iView = [[UIImageView alloc] initWithImage:image];
searchField.leftView = iView;
}
}
It works perfectly. But I worry that Apple may reject the app. I know this is not a private API, but also this is not fully public.
Does any one have app in App Store with such kind of code?
You are not calling any private API, so I'm almost sure that this code will pass the AppStore validation. Take note that your code is not future proof, it is possible that Apple will change the inner UISearchBar implementation and your code might stop working. The most reliable solution would be to subclass UITextField and roll out your own code.
Having said that, it is highly unlikely that this will become a problem, and it's a safe bet that your code will work.
in most case it would not be detected by apple. (too many apps use similar methods to modify UIControl)
but you need to check iOS version before run this code, apple dev team may change these inner structure in new iOS versions.
if (ios > 5.0 && ios < 6.0 )
// your modifies here
else
// ....

UIImage imageNamed not work on ios 5.0

I use this code:
[image setImage:[UIImage imageNamed:#"some#2x.png"]];
and it work on ios 4.3, but on ios 5.0 I don't see my image.
Anybody know which kind this problem?
You normally don't need to include the #2x in the name - iOS should automatically pick the right filename (some.png or some#2x.png) depending on the scale of the screen. Have you tried this:
[image setImage:[UIImage imageNamed:#"some.png"]];
instead?
As Martin (the other :) ) said, you should'nt add #2x if you have both yourImage.png and yourImage#2x.png.
I also listed many reasons of problems that could occurs with imageNamed here

Resources