UITextView on iPad INCREDIBLY Slow - iphone

I have an NSMutableArray of custom views (that are pretty much 1 UITextView and 1 UILabel with a custom back ground image), these are created as they are need (I start with 2 (though the first one is only 2 UITextFields and the other is normal) of these). Now my issue here seems to be this: as soon as I try to edit any UITextView past the one in the 2nd view, it starts to run incredibly slow, not the app, just the textview. For example, as I type, the little blinky guy lags behind the text and when I click to copy/paste/cut/etc you can see the little balloon fly in from the upper left corner every time. I have run the static analyzer for leaks and come up with nothing and run it alongside some other the testing software in XCode and it does not appear to have any reason for this.
Any help would be greatly appreciated.
EDIT Adding code
Custom UIView, all that's really called on each
-(id)initWithFrame:(CGRect)frame andIdentifier:(NSInteger)_t {
if ((self = [super initWithFrame:frame])) {
// Initialization code
self.image = [UIImage imageNamed:#"page.png"];
self.tag = _t;
self.userInteractionEnabled = YES;
self.clipsToBounds = YES;
drawImage = self.image;
text = [[UITextView alloc] initWithFrame:CGRectMake(40.0, 40.0, self.frame.size.width - 80.0, self.frame.size.height - 80.0)];
text.delegate = self;
Lbl = [[UILabel alloc] initWithFrame:CGRectMake(self.frame.size.width - 30, self.frame.size.height - 30, 20, 20)];
Lbl.text = [NSString stringWithFormat:#"%d",self.tag];
[self addSubview:text];
[self addSubview:Lbl];
[Lbl release];
}
return self;
After that, I store the view in an array in the view controller and then stack 2 (used to be 3) at a time with one front and foremost and one below it. These get shuffled a bit but thats about it. I do not think it is a device issue, just a weird error that I cannot seem to catch.

found my problem, apparently some obscure animation block got left opened, which apparently animated everything else that was going on on the UIKit side. odd but makes sense

Related

Xcode Scrollview slow

I have create a labels with in the scroll view. The for loop count is more than 1000. At the time the scroll is very slow. If the data is less amount (200, 300, ...) at the time its scroll smoothly. I am using the below code for create label.
UILabel *modelLabel;
UIButton *modelButton;
for (int i = 0; i < [modelArray count]; i++)
{
modelButton = [UIButton buttonWithType:UIButtonTypeCustom];
modelButton.frame = CGRectMake(0.0, (i * LABEL_HEIGHT), LABEL_WIDTH, LABEL_HEIGHT);
modelButton.tag = i+100;
[modelButton addTarget:nil action:#selector(modelButtonAction:) forControlEvents:UIControlEventTouchUpInside];
[modelScrollView addSubview:modelButton];
modelLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, (i * LABEL_HEIGHT), LABEL_WIDTH, LABEL_HEIGHT)];
modelLabel.text = [NSString stringWithFormat:#"%#", [[modelArray objectAtIndex:i] valueForKey:#"Model"]];
modelLabel.tag = i+1000;
modelLabel.backgroundColor = [UIColor clearColor];
modelLabel.textColor = [UIColor grayColor];
modelLabel.alpha = 0.5;
modelLabel.textAlignment = UITextAlignmentCenter;
modelLabel.font = EUROSLITE_FONT(14);
[modelScrollView addSubview:modelLabel];
}
[modelScrollView setContentSize:CGSizeMake(280.0, ([modelArray count] * LABEL_HEIGHT))];
How can I fix this issue?
Thanks in advance.
This happens to you because you load to many things to the memory
As the comment above said, It will be very easy to achieve using UITableView.
Although if you want more control, and you decide using scroll view you have to implement lazy loding. This is being done be allocating and placing the labels when it actually needed to be showen and not during the initialization. You will be able to know that by setting you view controller as the delegate and get the contentOffset from the scrollViewDidScroll: method. Also after recognizing you'll need te remove the subview in order to clear the memory
You can see good example for it here
I feel its because ios is trying to create and keep alot of these views in memory rather then create them dynamically(am I using that word right?) as they scroll on. It would be alot faster to use a UITableView that has a reuse identifier. This will stop iOs from creating a new allocation of memory for each view you make. Create a custom UTTableViewCell, with the labels and buttons you need that is created via a reuse identifier.
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
You should be able to find alot of resource on the web for creating a UITableView with a custom style. If you need a horizontal scrolling UITableView take a look at EasyTableView.

UISegmentedControl with Direction or Arrow theme

I have implemented UISegmentedControl with Direction theme using BASequenceControl from cocoacontrols.com.
I have added BASequenceControl.h and BASequenceControl.m classes and required images from GitHub
Great. Its working fine for me..However I have a concern with the last segment section tip.
Its displaying the junk space of last segment section.
Original Screen Shot
I need like this
The code I have Implemented
#import "BASequenceControl.h"
BASequenceControl *bASequenceControl = [[BASequenceControl alloc] init];
bASequenceControl.frame = CGRectMake(10, 10, 200, 44);
[bASequenceControl addSegmentWithTitle:#"First" animated:NO];
[bASequenceControl addSegmentWithTitle:#"Second" animated:NO];
bASequenceControl.leftMargin = -22;
bASequenceControl.rightMargin = 0;
bASequenceControl.overlapWidth = 22;
[self.view addSubview:bASequenceControl];
Any help on this is appreciated.
Thanks.
This is a pretty simple fix. You will have to edit the BASequenceControl.m file or you can duplicate the class and rename it.
The line that is causing the problem is in drawRect: it basically draws the grey arrow across the entire background of the control. Creating that nice gradient in the empty space.
[passiveSegmentImage drawInRect:CGRectMake(-passiveSegmentImage.size.width, 0,
w + 2 * passiveSegmentImage.size.width, h)];
You can change it to:
[passiveSegmentImage drawInRect:CGRectMake(0, 0,
w, h)];
Now you have to tell the control that it should not be opaque. Update the initializers like this.
- (void)awakeFromNib {
_selectedSegmentIndex = -1;
[self setOpaque:NO];
[super awakeFromNib];
}
- (id)init {
if ((self = [super init])) {
[self setOpaque:NO];
_selectedSegmentIndex = -1;
}
return self;
}
This is pretty quick and dirty, you could potentially make this settable with a property. Then submit a pull request to BaseAppKit, but I'll leave that to you. Here is a gist that you can copy and paste directly in BASequenceControl.m to fix the overhang.
https://gist.github.com/4632686
Edit: Make sure that you are using init as the initializer and then setFrame: (I'm not really sure why initWithFrame: wasn't overridden in the class.)
BASequenceControl *control = [[BASequenceControl alloc] init];
[control setFrame:CGRectMake(0, 0, 300, 40)];
Green background for dramatic effect
How about to use a mask like this :
to mask your SegmentedControl

UISegmentedControl not centered on UINavigationController when added programmatically

I'm using the following code in my root view controller class implementation:
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *segmentTextContent = [NSArray arrayWithObjects:
NSLocalizedString(#"button1", #""),
NSLocalizedString(#"button2", #""),
NSLocalizedString(#"button3", #""), nil];
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] nitWithItems:segmentTextContent];
segmentedControl.selectedSegmentIndex = 0;
segmentedControl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.frame = CGRectMake(0, 0, 400, 30);
self.navigationItem.titleView = segmentedControl;
[segmentedControl release];
}
The segmented control is not centered correctly, it is shifted a few pixels to the right. The funny thing is, it is not right-aligned either. It's as if there is some left padding preventing it from being centered. Another funny thing is, if I draw this segmented control in interface builder, it centers perfectly, so this is only a programmatic issue.
I've tried this code in a brand new empty app and get the same results, so I know it's not something else in my app that is causing it.
Sorry, I wanted to post a screen shot, but I don't have enough reputation points ;-)
Any Ideas?
There is no left button, I've even tried doing:
self.navigationItem.leftBarButtonItem = nil;
self.navigationItem.backBarButtonItem = nil;
As I said, it works in IB, just not in code. And it also fails in a brand new project - you can try it for yourself, and see...
I seemed to have found the fix. The 400 specified for the width was causing the problem. I specified 300, and now it is centered correctly. I supposed ideally I should be grabbing some global screen width value instead of hard-coding 300.

iPhone function to create UILabel fails and crashes

I have a view with a scrollview. I use code to add labels to the scrollview. Since there's a lot of redundant code, I tried to move the label creation to a separate function that returns a UILabel. Here' that function:
- (UILabel *) f_MakeLabelWithL:(float)MyLeft T:(float)MyTop W:(float)MyWidth H:(float)MyHeight Align:(UITextAlignment)MyAlign
Font:(UIFont *)MyFont TextColor:(UIColor *)MyTextColor BGColor:(UIColor *)MyBGColor {
CGRect rect = CGRectMake(MyLeft, MyTop, MyWidth, MyHeight);
UILabel *label = [[[UILabel alloc] initWithFrame:rect] autorelease];
label.adjustsFontSizeToFitWidth = YES;
label.backgroundColor = MyBGColor;
label.font = MyFont;
label.numberOfLines = 0;
label.textAlignment = MyAlign;
label.textColor = MyTextColor;
return label;
}
I set the text of the label after it is returned. Or so I intended. In fact, a label that is told to have a blue background appears as a solid black rectangle. One with a clear background is entirely clear. Worse than that: the scrollview won't scroll, and attempting to make it do so crashes the app without any explanation in the debugger console.
Yet all this code works inline just fine and dandy.
Anyone know why?
Update: Putting the code inline fixed the display of the labels. But I was also using a function to create images:
- (UIImageView *) f_MakeImageWithL:(float)MyLeft T:(float)MyTop W:(float)MyWidth H:(float)MyHeight File:(NSString *)MyFile {
CGRect rect = CGRectMake(MyLeft, MyTop, MyWidth, MyHeight);
UIImageView *oImageView = [[[UIImageView alloc] initWithFrame:rect] autorelease];
NSString *s = [[Isystant f_DocumentsPath] stringByAppendingPathComponent:MyFile];
UIImage *oImage = [UIImage imageWithContentsOfFile:s];
[oImageView setImage:oImage];
oImageView.backgroundColor = [UIColor redColor];
oImageView.opaque = YES; // explicitly opaque for performance
return oImageView;
}
It was creating the images, but the frozen scroll/crash problem didn't go away until I put this code back inline also.
Looks to me like you are over-releasing the UILabel. You shouldn't have to release the label after adding it to your scrollview if it was never retained anywhere prior to that (and you've autoreleased it in the makeImageWithL method).
That's probably why it is working when you put it inline... because in that scenario, I would bet you are removing the autorelease, right?
-S
Do you retain your returned Label somewhere?

subclassed UITableViewCell - backgroundView covers up anything I do in drawRect

I'm trying to make a subclassed UITableViewCell where I draw an image in the upper right corner. I have it working perfectly - except when I set self.backgroundView, my background image covers up the image drawn in drawRect.
There must be a way to be able to set a background image (and the selectedBackgroundView) without covering up what's being done in drawRect.
Am I going about this the wrong way?
EDIT: I've posted an example project with the problem.
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
// TODO: figure out why this covers up self.starImage that's drawn in drawRect
self.backgroundView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cellBackground.png"]] autorelease];
}
return self;
}
- (void)drawRect:(CGRect)rect {
[self.starImage drawAtPoint:CGPointMake(self.bounds.size.width - self.starImage.size.width, 0.0)];
}
EDIT 2: at AWrightIV's request, here's how I got it working... which didn't require subclassing UITableViewCell at all. I'm just adding a subview to cell.backgroundView:
// create a UIImageView that contains the background image for the cell
UIImageView *bgImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cellBackground.png"]];
// create another UIImageView that contains the corner image
UIImage *starRedImage = [UIImage imageNamed:#"starcorner_red.png"];
UIImageView *starImageView = [[UIImageView alloc] initWithFrame:CGRectMake(297,
0,
starRedImage.size.width,
starRedImage.size.height)];
starImageView.image = starRedImage;
// add the corner UIImageView as a subview to the background UIImageView
[bgImageView addSubview:starImageView];
// set cell.background to use the background UIImageView
cell.backgroundView = bgImageView;
You are not really supposed to mix the drawing with your cell like that, you are operating at a lower-level than the UITableViewCell machinery is operating, and this is why you get this problem.
This is just one of the various problems you will end up running into. You will run into other problems as you go down that path, including problems with how the selection works.
The proper approach is to create a custom UIView that contains the code to draw, and then you can addSubView that into your cell's root view. That will take care of the rendering in the proper order, and wont interfere with the selection system, and will work correctly in this case.
You shouldn't override the -drawRect: of a tablecell. Instead, create a new custom view and add it to the cell's contentView, and draw in there.
Have you tried adding a [super drawRect:rect]; there?
Here's a solution that's a bit of a kludge, but it fits my requirements exactly... with one fatal flaw: when cells get reused, the star corner shows up when I don't want it to.
http://dl.dropbox.com/u/2349787/UIImage_Position_subclassed_cell2.zip
I'm still using drawRect here, but only because self.starImage is null if you access it within the initWithStyle method. Also, instead of adding the subview to self.contentView, I'm adding it to self.backgroundView to prevent the cell's delete button from interfering with it. The star corner is positioned correctly in both portrait and landscape mode, and works fine within edit mode as well.
With the cell reuse issue though, It's still a no go... so, maybe I'm back to trying to do it without subclassing UITableViewCell.
I'm open to any further suggestions. Thank you!
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
// Initialization code
self.backgroundView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cellBackground.png"]] autorelease];
}
return self;
}
- (void) drawRect:(CGRect)rect {
UIImageView *imageView = [[[UIImageView alloc] initWithFrame:CGRectMake(self.bounds.size.width - self.starImage.size.width, 0, self.starImage.size.width, self.starImage.size.height)] autorelease];
imageView.image = self.starImage;
imageView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
[self.backgroundView addSubview:imageView];
}