Creating 1000 views in a scroll view takes time - iphone

I am creating 1000 views in a scrollview. This takes more time to load the view.
wordsDetails *wordsObj;
for(int i = 0; i<arrayOfWords.count;i++) {
UIView *viewForDisplay = [[UIView alloc]initWithFrame:CGRectMake(320*i, 0, 320, 440)];
UILabel *wordLabel = [[UILabel alloc]initWithFrame:CGRectMake(30, 40, 240, 40)];
wordLabel.backgroundColor = [UIColor clearColor];
wordLabel.textColor = [UIColor yellowColor];
wordLabel.font = [UIFont fontWithName:#"Didot" size:24.0];
wordsObj = [arrayOfWords objectAtIndex:i];
wordLabel.text = wordsObj.word;//[NSString stringWithFormat:#"sdssds - %i",i];
[viewForDisplay addSubview:wordLabel];
UITextView *textView = [[UITextView alloc]initWithFrame:CGRectMake(30, 100, 240, 100)];
textView.text = wordsObj.meaning;
textView.editable = NO;
textView.textColor = [UIColor whiteColor];
textView.font = [UIFont fontWithName:#"Didot" size:20.0];
textView.backgroundColor = [UIColor clearColor];
[viewForDisplay addSubview:textView];
[fScrollView addSubview:viewForDisplay];
}
Is there a way to call this in thread.

Don't do it like this. Use a cell-based scrollview subclass (table view or collection view) or roll your own. Your content is the width of the screen so there is absolutely no need to load 1000 screens worth of content at once.
With the cell-based views you only create as many as are needed to show a screen, and these are recycled and reconfigured as new content comes on screen.

I am creating 1000 views in a scrollview.
Don't do that. The user can't possibly use 1000 views all at once, so don't create them all at once. There are some good videos from WWDC 2010, 2011, and 2012 that cover tiling the content in scroll views -- take a look at those for some great ideas.
The scroll view delegate gets messages as the scroll view's content moves, and you can use those messages to add content just in time for it to scroll onto the screen and remove it after it has scrolled off. This is essentially what UITableView and UICollectionView do, and you can use either of them as jrturton suggests, or you can follow the same pattern yourself.
This will not only speed up the creation of your scroll view, it'll also make your scrolling smoother and consume much less memory than you would need otherwise.

Related

iOS - trying to rotate a text label and the label disappears

I'm trying to rotate a label on my view 90 degrees. I've tried the two following ways to do it and the label just disappears from the screen. I triple checked that the properties are properly attached. Any thoughts?
attempt one:
// rotating labels 90 degrees
self.labelCloseScroll.transform = CGAffineTransformMakeRotation (3.14/2);
attempt two:
CGAffineTransform rotate = CGAffineTransformMakeRotation(3.14/2);
rotate = CGAffineTransformScale(rotate, 1, 1);
[self.labelCloseScroll setTransform:rotate];
I am not 100% sure if it works or not but why are you not using M_PI_2. It's just simple thought that you are assuming Value of Pi to be 3.14 but the exact value is 3.14159...
I did it like this and it worked fine :
UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 50, 70)];
lbl.text = #"New";
lbl.backgroundColor = [UIColor clearColor];
lbl.textColor = [UIColor whiteColor];
lbl.highlightedTextColor = [UIColor blackColor];
lbl.font = [UIFont systemFontOfSize:12];
lbl.transform = CGAffineTransformMakeRotation(M_PI_2);
[self.view addSubview:lbl];
You can also check Answers from these Questions :
How to Render a rotated UIlabel
Rotating UILabel at its center
Hope it will be helpful for you.
It may simply be that the view's bounds have become too small for the text. When the text can't be fully displayed in label view in iOS, it simply disappears, rather than remaining on show. Perhaps it's a deliberate Apple policy to prevent apps shipping with clipped text and forcing the dev to fix ;)
It sounds very much as though this is what is happening. You have said the text gets smaller as you rotate it, which indicates you have the shrink text to fit property set on the label view. This will shrink the text as the constraining view reduces in size. But the text will only shrink so much before it disappears.
If the label view itself would seem to be big enough, also be sure to check the bounds of each parent view the label is contained in, up through the view hierarchy.

tableView as subview in a semi-transparent view

I'm developing a little iOS component and I have a problem with a semi-transparent view with subviews. This is my scenario:
- one view with a semi-transparent background using [UIColor colorWithRed:green:blue:alpha]
- a little UITableView, with alpha = 1.0, added as a subview to the semi-transparent view
- some other subviews
Everything works well but the problem raises when the UITableView is scrolled up or down, in fact the area of the semi-transparent view around the UITableView loses its transparency becoming darker than its original background color.
Here's an image to explain the problem:
Look at the space with the two arrows...
Can anyone help me with this problem?
Thank you so much for your attention!
Update:
Some code:
_alertBg = [[UIView alloc] initWithFrame:CGRectZero];
_alertBg.backgroundColor = self.backgroundColor;
_alertBg.frame = CGRectMake((_bgView.frame.size.width - 240) / 2, (_bgView.frame.size.height - 260) / 2, 240, 260);
_alertBg.layer.cornerRadius = 8.0;
_alertBg.layer.borderWidth = 2.0;
_alertBg.layer.borderColor = self.borderColor.CGColor;
_alertBg.layer.shadowColor = [UIColor grayColor].CGColor;
_alertBg.layer.shadowOffset = CGSizeMake(0, 3);
_alertBg.layer.shadowOpacity = 0.8;
_alertBg.layer.masksToBounds = YES;
[_bgView addSubview:_alertBg];
_table = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
_table.frame = CGRectMake(10, _titleLabel.frame.origin.y + _titleLabel.frame.size.height + 12, _alertBg.frame.size.width - 20, 150);
_table.layer.cornerRadius = 6.0;
_table.layer.masksToBounds = YES;
_table.delegate = self;
_table.dataSource = self;
[_alertBg addSubview:_table];
From the code above, self.backgroundColor is something like [UIColor colorWithRed:0 green:0 blue:1 alpha:0.7]
I put the available code in a test project, and got the same problem as you have. Commenting out _alertBg.layer.shadowOpacity = 0.5; fixes the issue for me. Maybe someone can clarify why is this an issue, I have limited experience with QuartzCore.
EDIT: Okay, inched closer to the real reason. It seems that if you don't have set the _alertBg.layer.shadowPath property all kinds of crazy things happen when you scroll the table (my guess here is that the table scroll calls a redraw of the _alertBg and the shadow redrawing gets called in quick succession far too many times and you get those visual artifacts).
Adding a shadowPath fixes the problem, so the layer code for the _alertBg should be as following:
_alertBg.layer.cornerRadius = 8.0;
_alertBg.layer.borderWidth = 2.0;
_alertBg.layer.borderColor = [UIColor colorWithRed:0 green:0 blue:1 alpha:0.7].CGColor;
_alertBg.layer.shadowColor = [UIColor grayColor].CGColor;
_alertBg.layer.shadowOffset = CGSizeMake(0, 5);
_alertBg.layer.shadowOpacity = 0.8;
_alertBg.layer.shadowPath = [UIBezierPath bezierPathWithRect:_alertBg.bounds].CGPath;
_alertBg.layer.masksToBounds = YES;
Just fix the shadowPath to your liking and you should be ready to go.
PS: On my Google-quest I found this excellent blog post about shadows, it might be of help.
Maybe match the background colour of tableView with _alertBg?
Its may be problem of dequeueReusableCellWithIdentifier.
just try this..., set dequeueReusableCellWithIdentifier to nil like bellow in cellForRowAtIndexPath method of UITableViewController delegate method
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
Also see my this answer may be you can get some idea from this..
iPhone Hide/Show labels in Uitableview cell

Add tableview in scrollview with table scrolling disabled in Iphone

I have scroll view with label and a table view and a button . I just want to scroll the scrollview and the table view must display all the contents but tableview must not scroll. Below the tableview i have a button. How to set the frame of the button so it comes exactly below the table?
Thanks
Maybe you would like to set the YourTableView.userInteractionEnabled = NO?
Yes we can disable the scrolling the tableview.
Goto->xib->select table->Goto 1st tab->unselect the scrolling Enabled.
The answer for your Second Question.
Put the UiView in footer of your table and then place the button in that UIView you want to show in bottom.
It will always show at the bottom.
If you want to place button programmatically use following code in viewDidload method.
///--------Table Footer is Set here
UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 260, 44)];
UIButton *adddays = [[UIButton alloc] initWithFrame:CGRectMake(10, 0, 260, 44)];
[adddays setBackgroundImage:[UIImage imageNamed:#"abcd.png"] forState:UIControlStateNormal];
[adddays addTarget:self action:#selector(buttonaction) forControlEvents:UIControlEventTouchDown];
UILabel *text = [[UILabel alloc] initWithFrame:CGRectMake(75, 12, 250, 20)];
[text setBackgroundColor:CLEAR_COLOR];
[text setText:#"Title for your button"];
[text setTextColor:XDARK_BLUE];
text.font=[UIFont fontWithName:#"Arial-BoldMT" size:18.0f];
[footer addSubview:adddays];
[footer addSubview:text];
[table setTableFooterView:footer];
This is assuming you have created IBOutlets for your scrollView, tableView and button, and hooked them up appropriately.
I find it useful to remember that we're only messing with the y-values of a CGRect (origin.y & size.height) - The x-values should be set up in the xib.
I've commented this profusely to illustrate my point better, usually I would only comment where appropriate
-(void)viewDidLoad {
[self.tableView setScrollEnabled:NO];
// Get the number of rows in your table, I use the method
// 'tableView:numberOfRowsInSection:' because I only have one section.
int numOfRows = [self.tableView numberOfRowsInSection:0];
// Get the height of your rows. You can use the magic
// number 46 (44 without including the separator
// between rows) for the height of your rows, but because
// I was using a custom cell, I had to declare an instance
// of that cell and exctract the height from
// cell.frame.size.height (adding +2 to compensate for
// the separator). But for the purpose of this demonstration
// I'm going to stick with a magic number
int rowHeight = 46; //Eww, Magic numbers! :/
// Get a reference to the tableViews frame, and set the height
// of this frame to be the sum of all your rows
CGRect frame = self.tableView.frame;
frame.size.height = numOfRows * rowHeight;
// Now we have a frame with the exact size of our table,
// so set the 'tableView.frame' AND the 'tableView.contentSize'
// to that. (Because we want ALL rows visible as you
// disabled scrolling for the 'tableView')
self.tableView.frame = frame;
self.tableView.contentSize = frame.size;
// Now we want to set up the button beneath the table.
// We still have the 'frame' variable, which gives us
// the tableView's Y-origin and height. We just add these
// two together (with +20 for padding) to get the origin of the button
CGRect buttonFrame = self.button.frame;
buttonFrame.origin.y = frame.origin.y + frame.size.height + 20;
self.button.frame = buttonFrame;
// Finally, we want the `scrollView`'s `contentSize` to
// encompass this entire setup (+20 for padding again)
CGRect scrollFrame = self.scrollView.frame;
scrollFrame.size.height = buttonFrame.origin.y + buttonFrame.size.height = 20;
self.scrollView.contentSize = scrollFrame.size;
}
You could stop the scrolling the table view. But you shouldn't be adding a tableview inside a scrollview. UITableView is subclass of UIScrollView and adding one scrollView on another will create problem. I suggest you to remove the scrollview and use the tableview alone ( as the tableview itself is a scrollview).

Putting a graphical frame/border around a table

I've a few tables in my app. At the moment they are a plain standard transparent table.
You can see the background image behind the table and thats ok.
Put the table looks strange and maybe out of place because it is not obvious its a table.
Is there some option( i couldnt find any) for adding a frame/boarder(like a picture frame) around the table that the table can scroll inside of? I've searched though table and didnt see any.
So if thats true then that leaves me needing to draw a graphic over the table so that the table appears inside it. Any advise welcome.
EDIT:
CGRect cgRct = CGRectMake(30, 50, 270, 350);
table = [[[UITableView alloc] initWithFrame:cgRct
style:UITableViewStylePlain]autorelease];
table.backgroundColor = [UIColor clearColor];
table.layer.borderWidth = 5;
table.layer.borderColor = [UIColor redColor];
table.dataSource = self;
table.delegate = self;
[self.view addSubview:table];
Added this code and the import of Quartz.
But no boarder was drawn.
You can use its layers' properties:
#import <QuartzCore/QuartzCore.h>
tableView.layer.borderWidth = 1.0;
tableView.layer.borderColor = [UIColor redColor].CGColor;
You could also make the tableview smaller on all sides and the have that sit on an image of a frame.

Big activity indicator on iPhone

Does anyone know how to show a rounded squared with a spinning activity indicator? It is used in many apps. If you don't know what im talking about, it looks like the indicator when you change volume on your Mac but with a darker background. Im not sure if it is built-in to iOS or someone made it.
Like the one in this post but not full screen just the activity indicator
How to create a full-screen modal status display on iPhone?
Here's what I use when I want to show that kind of indicators.
UIView *loading = [[UIView alloc] initWithFrame:CGRectMake(100, 200, 120, 120)];
loading.layer.cornerRadius = 15;
loading.opaque = NO;
loading.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.6f];
UILabel *loadLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 25, 81, 22)];
loadLabel.text = #"Loading";
loadLabel.font = [UIFont boldSystemFontOfSize:18.0f];
loadLabel.textAlignment = UITextAlignmentCenter;
loadLabel.textColor = [UIColor colorWithWhite:1.0f alpha:1.0f];
loadLabel.backgroundColor = [UIColor clearColor];
[loading addSubview:loadLabel];
[loadLabel release];
UIActivityIndicatorView *spinning = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
spinning.frame = CGRectMake(42, 54, 37, 37);
[spinning startAnimating];
[loading addSubview:spinning];
[spinning release];
loading.frame = CGRectMake(100, 200, 120, 120);
Then you just add the 'loading' view to the view of your choice and you got it.
Hope this is what you needed.
Your screenshot is probably a usage of David Sinclair's DSActivityView module. Specifically, the DSBezelActivityView component of it. Or if not, it's a close copy.
http://www.dejal.com/developer/dsactivityview
I use DSActivityView all the time. Great library. Toss that thing up while pulling down data, keeps users and clients happy.
One option: MBProgressHUD.
I don't think that screenshot is my DSBezelActivityView; the metrics look a little different. But it is very similar.
Note, DSActivityView and its subclasses don't use any images or nibs; they're pure code.
To answer the original question, it'd be easy to modify DSBezelActivityView to omit the fullscreen gray background. You could do it by subclassing and overriding the -setupBackground method thusly:
- (void)setupBackground;
{
[super setupBackground];
self.backgroundColor = [UIColor clearColor];
}
Hope this helps!
Try this simple method, Its working well for me....
UIActivityIndicatorView *activityIndicator= [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(0, 0, 50, 50)];
activityIndicator.layer.cornerRadius = 05;
activityIndicator.opaque = NO;
activityIndicator.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.6f];
activityIndicator.center = self.view.center;
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
[activityIndicator setColor:[UIColor colorWithRed:0.6 green:0.8 blue:1.0 alpha:1.0]];
[self.view addSubview: activityIndicator];
You're actually looking at using two UIView subclasses and a custom .png image to get the look you want.
The Gray translucent box would be a UIImageView object, to get the effect you're looking for you need a .png file of a grey square with rounded corners, it doesn't need to be the final size, as long as there's at least one pixel of straight edge between the corners it will work fine. You'll then load it in as a UIImage with the UIImage
stretchableImageWithLeftCapWidth:topCapHeight: method, this let's you specify the top, and left portions of the image that must stay the same, and a 1 pixel slice in each direction will be stretched out to fill the UIImage view you use the image in. http://www.bit-101.com/blog/?p=2275 has a great example of how this works.
So create a UIImage, then create a UIImageView using this image, set its opaque property to NO and the alpha property to something that looks good to you. Add this a subview of your current view.
Now you just need to add the spinning progress indicator, this is even easier, just create a new UIActivityIndicatorView and add it as a subview of the UIImageView you've already created.
The same basic method is used to create pretty much any resizable element in an iOS application. There's some examples of using them for buttons in Apple's UICatalog example code.