Debugging app artwork slow down in Objective-C - iphone

I have a tableviewcontroller, specifically, in my app which is getting a little jittery when scrolling.
I fairly certain it's because of my custom UISegmentedControl appearance, I have four in my table, each in their own cell.
I use this code in my app delegate to customise them:
[[UISegmentedControl appearance] setBackgroundImage:[[UIImage imageNamed:#"SegmentedControl.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 4, 0, 4)] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setBackgroundImage:[[UIImage imageNamed:#"SegmentedControlSelected.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 4, 0, 4)] forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:[UIImage imageNamed:#"SegmentedControlDivider.png"] forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:[UIImage imageNamed:#"SegmentedControlSelectedDivider.png"] forLeftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:[UIImage imageNamed:#"SegmentedControlSelectedDivider.png"] forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
[UIColor whiteColor], UITextAttributeTextColor,
[UIColor grayColor], UITextAttributeTextShadowColor,
[NSValue valueWithUIOffset:UIOffsetMake(0, -1)], UITextAttributeTextShadowOffset,
[UIFont fontWithName:#"Georgia-Italic" size:0.0], UITextAttributeFont,
nil] forState:UIControlStateNormal];
Why might this cause such a slow down? What could I do to improve performance? It jitters as they come onto the screen. I have never had a problem like this before.
I'm fairly sure its the switches and segmented controls, as when I remove them it speeds up and goes all silky smooth. I basically do this:
if (indexPath.row == 0)
{
cell.textLabel.text = #"text";
UISegmentedControl *segControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"1", #"2", nil]];
[segControl setSelectedSegmentIndex:[myBool boolValue]];
[segControl setSegmentedControlStyle:UISegmentedControlStyleBar];
[segControl addTarget:self action:#selector(myMethod:) forControlEvents:UIControlEventValueChanged];
cell.accessoryView = segControl;
}
In my cellForRowAtIndexPath 7 times, how can I make this faster?

I have an app that I am working on and I had some similar customizations. I recommend reusing the set controls... You can accomplish this by making a UITableViewCell subclass and setting up your seg control in it, then you can create outlets for the things you need to customize.
A quick search found this tutorial and it looks like what I am talking about
UITableViewCell Prototype Tutorial
This way your cells will be completely reusable and therefore, much faster.
But then, I don't now your exact use case, so maybe this won't apply to you. It sped up my cells with custom buttons, art, and animations quite a bit.
Just remember alloc inits are very slow.
I guess another option would be to pre-init all that you can with the controls and maybe store them in and array then only load them in cellForRowAtIndexPath:

Related

customize UIBarButtonItem initWithBarButtonSystemItem to show up as grey not white in iOS 5

I am using a white background on my UINavigationBar with darkGrayColor text
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"uinavigationcontrollerbackground"] forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:font,UITextAttributeFont ,[UIColor darkGrayColor], UITextAttributeTextColor, [UIColor whiteColor], UITextAttributeTextShadowColor, nil]];
Which looks nice but I have buttons defined like this throughout my app:
self.searchButton =[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:#selector(searchProducts)];
I killed the default blakc background look I had going like this:
[[UIBarButtonItem appearance] setBackgroundImage:[UIImage imageNamed:#"uibarbuttonbackground"] forState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
Which is just a white square.
Now my icons are still white with a light gray shadow, anyway to change these default icons?
Once I tried to change background of UIBarButtonSystemItemCamera but nothing worked. I guess these default system button types (UIBarButtonSystemItem )come with a background image already, so changing it won't do.
I recommend you to create a custom view and init your bar button with it. Not a perfect code but I hope it helps.
UIImage *image = [UIImage imageNamed:#"icon.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setBackgroundImage: [image stretchableImageWithLeftCapWidth:7.0 topCapHeight:0.0] forState:UIControlStateNormal];
button.frame= CGRectMake(0.0, 0.0, image.size.width, image.size.height);
[button addTarget:self action:#selector(takePicture:) forControlEvents:UIControlEventTouchUpInside];
UIView *v=[[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, image.size.width, image.size.height) ];
[v addSubview:button];
UIBarButtonItem *barItem = [[[UIBarButtonItem alloc] initWithCustomView:v] autorelease];
I used the category solution found here, it is working great:
UIBarButtonItem with custom image and no border
I little more work than I was hoping but it is a nice clean solution.

Strange behavior of UIBarButtonItem when using UIAppearance

I'm customizing the elements like navigation bar, tab bar and uibarbuttonitem using UIAppearance. It works very well except for a very strange behavior of the UIBarButtonItem elements. On the top level of the navigation controller hierarchy everything looks good, but if I push the next view controller, the UIBarButtonItem elements move a little bit downwards, but at the same time, the back button stays at its correct position. I attached two images to illustrate my problem.
1) First view controller in the navigation controller hierarchy
2) Second view controller in the navigation controller hierarchy
EDIT: The code
//Change navigation bar appearance
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"GPNavigationBarBackground.png"] forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];
[[UINavigationBar appearance] setShadowImage:[UIImage imageNamed:#"GPNavigationBarShadow.png"]];
[[UINavigationBar appearance] setTitleTextAttributes:
[NSDictionary dictionaryWithObjectsAndKeys:
[UIColor whiteColor], UITextAttributeTextColor,
[UIFont boldSystemFontOfSize:17], UITextAttributeFont,nil]];
[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:2.f forBarMetrics:UIBarMetricsDefault];
UIImage *buttonBackground = [[UIImage imageNamed:#"GPNavigationBarButton.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 10, 0, 10)];
UIImage *buttonPressedBackground = [[UIImage imageNamed:#"GPNavigationBarButtonPressed.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 10, 0, 10)];
UIImage *backButtonBackground = [[UIImage imageNamed:#"GPNavigationBarBackButton.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 10)];
UIImage *backButtonPressedBackground = [[UIImage imageNamed:#"GPNavigationBarBackButtonPressed.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 10)];
[[UIBarButtonItem appearance] setBackgroundImage:buttonBackground forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackgroundImage:buttonPressedBackground forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonBackground forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonPressedBackground forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonBackgroundVerticalPositionAdjustment:1.f forBarMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackgroundVerticalPositionAdjustment:1.f forBarMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setTitlePositionAdjustment:UIOffsetMake(0, 1.f) forBarMetrics:UIBarMetricsDefault];
Well, after brooding on that problem, I finally solved it. The code above is absolutely correct. The only problem was the height of the background images for the UIBarButtonItem. The UIAppearance proxy lets you set all the graphics, but it doesn't allow you to alter the height of the UIBarButtonItem.
So, when customizing UIBarButtonItem, always remember that a
UIBarButtonItem can't be higher than 30pt. That means that custom artwork shouldn't exceed this size.
You can set background images that are higher than 30pt, but you will run into the same problem as stated above.

How can I make setEnabled work on a customised UISegmentedControl in iOS5?

I have a UISegmentedControl in my iPad app which I have customised with the new methods available in iOS5, as below:
[[UISegmentedControl appearance] setBackgroundImage:segmentUnselected forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setBackgroundImage:segmentSelected forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentUnselectedUnselected forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentSelectedUnselected forLeftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segUnselectedSelected forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
NSDictionary *textAttributes = [NSDictionary dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:17], UITextAttributeFont,
[UIColor colorWithRed:0.3 green:0.34 blue:0.42 alpha:1], UITextAttributeTextColor,
[UIColor whiteColor], UITextAttributeTextShadowColor,
CGSizeMake(0, 1), UITextAttributeTextShadowOffset, nil];
[[UISegmentedControl appearance] setTitleTextAttributes:textAttributes forState:UIControlStateNormal];
It looks fine and works ok, but there's a problem in that calling setEnabled:NO on any of the segments has no effect - the segment will still respond to touch events. Does anybody know what I need to do to disable some of the segments?
Use isEnabledForSegmentAtIndex: and setEnabled:forSegmentAtIndex: found in the documentation for UISegmentedControl. Let me know if that gets it working.
Not sure if this is still an issue for anyone (since it's fixed in iOS 6, but here's the workaround that worked from me (borrowed from another question):
In your viewDidLoad, try:
dispatch_async(dispatch_get_main_queue(),^{
[self.segmentedControl setEnabled:NO forSegmentAtIndex:2];
});
It seems that when the views load, the presence of an appearance proxy resets the other properties of the UISegmentedControl. Scheduling this on the main thread will re-enable/re-disable. This also BTW works for selecting the default segment.

how to change the color of backBarButtonItem?

In my application I want to change the color of bacBarButtonItem.
Is it possible to change the color? or I have to put an image of it.
and in case of image tell me the code how to put the image.
If you just want to change the color you can do it with this line of code.
[[UIBarButtonItem appearance] setTintColor:[UIColor redColor]];
Replace redColor with the following to adjust the color of the buttons:
colorWithRed:0/255.0 green:144/255.0 blue:200/255.0 alpha:1.0// pick your color using this
Be sure to put this in the view controller that pushes. Not the view controller where you want to see this back button color.
Praveen-K answer is right, but take in mind that you'll have to do it in every viewcontroller.
Starting at iOS5, Apple have introduced the "appearance" concept.
- (void)setBackButtonBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_5_0) UI_APPEARANCE_SELECTOR;
In your case would be something like this
UIImage *image = [UIImage imageNamed:#"imageName.png"];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:image forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
But as I said, Praveen-K answer is ok and will work, but just to let you know for the future.
UIImage *image = [UIImage imageNamed:#"imageName.png"];
UIBarButtonItem* backBarButton = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:#selector(backButtonAction)];
self.navigationItem.leftBarButtonItem=backBarButton;
[backBarButton release];
Another way to change the color of back bar button item is to use segment control
UISegmentedControl *button = [[[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Back", nil]] autorelease];
button.frame = CGRectMake(0, 0, 60, 30);
button.center = self.view.center;
button.momentary = YES;
button.segmentedControlStyle = UISegmentedControlStyleBar;
button.tintColor = [UIColor colorWithRed:0 green:0.1 blue:0.5 alpha:0];
[button addTarget:self action:#selector(handleBack:) forControlEvents:UIControlEventValueChanged];
UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
Notice that we assign the color we want to the property tintColor of UISegmentedControl.
I got the idea from this site:
http://charles.lescampeurs.org/2011/02/10/tint-color-uibutton-and-uibarbuttonitem

How can I change the font color of a UIBarButton item?

I want to change the color to red.
I found a simpler way to just change the color of title:
iOS7:
UIBarButtonItem *button =
[[UIBarButtonItem alloc] initWithTitle:#"Title"
style:UIBarButtonItemStyleBordered
target:nil
action:nil];
[button setTitleTextAttributes:
[NSDictionary dictionaryWithObjectsAndKeys:
[UIColor redColor], NSForegroundColorAttributeName,nil]
forState:UIControlStateNormal];
and prior iOS7:
UIBarButtonItem *button =
[[UIBarButtonItem alloc] initWithTitle:#"Title"
style:UIBarButtonItemStyleBordered
target:nil
action:nil];
[button setTitleTextAttributes:
[NSDictionary dictionaryWithObjectsAndKeys:
[UIColor redColor], UITextAttributeTextColor,nil]
forState:UIControlStateNormal];
This question was answered here. Basically, you have to create a UIButton, configure it as you wish, and then initialize the Bar Button Item with the UIButton as a custom view.
There are Two ways to change the color of the Text displayed UIBarButtonITem.
1)
[barButtonITem setTintColor:[UIColor redColor]];
2) or you can you any UIColor class method. this is really efficient solution.Althought for iOS 7 you can use NSForegroundColorAttributeName and can use
barButtonItem setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor clearColor],NSForegroundColorAttributeName, nil] forState:UIControlStateNormal];
On similar note from Guvvy Ava you can change font size like
[buttonItem setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: [UIFont fontWithName:#"Helvetica-Bold" size:26.0], UITextAttributeFont,nil] forState:UIControlStateNormal];
swift version 4.0 or later
barButtonITem.tintColor = UIColor.red // for textColor change
if want to change font as well as text color use the following code
barButtonITem.setTitleTextAttributes([NSAttributedStringKey.foregroundColor :UIColor.red,NSAttributedStringKey.font:UIFont.init(name:"Avenir", size:15.0)], for: UIControlState.normal)
If you are using system Navigation bar button item then to change your button tint color use
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
To change button text color use the following code also.
[[UIBarButtonItem appearance] setTitleTextAttributes:#{NSForegroundColorAttributeName:[UIColor whiteColor]} forState:UIControlStateNormal];
Add the following line of code which viewcontroller you want to change your color