I have a large amount of image buttons being added to the screen in an iPhone app. Everything is working fine with my code.
The problem is the subviews are not displaying until every one of the subviews are ready to display. So for example I have 48 subviews, I don't want to wait until every subview is ready, I want to visibly be able to see each one appearing on the screen as they are loading.
I hope this makes sense. The issue is getting larger as i add more images to the collection.
This is my code for you to see:
for (int i = 0; i < imgNumbers.count; i++) {
myButton = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect buttonValue = [[btn9Locations objectAtIndex:location] CGRectValue];
myButton.frame = buttonValue;
NSString *imagePart1 = [[NSString alloc] initWithFormat:#"%#", imgNumbers[i]];
[myButton addTarget:self action:#selector(buttonClick:) forControlEvents:UIControlEventTouchDownRepeat];
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
NSURL *fileURL = [tmpDirURL URLByAppendingPathComponent:imagePart1];
NSString *imageLocation = [[NSString alloc]initWithFormat:#"%#", [fileURL path]];
UIImage * image = [UIImage imageWithContentsOfFile:imageLocation];
[myButton setBackgroundColor:[UIColor colorWithRed:0.94 green:0.39 blue:0.13 alpha:0.0]];
[myButton setBackgroundImage:image forState:UIControlStateNormal];
[myButton setTitle:[imageNames[i] uppercaseString] forState:UIControlStateNormal];
[myButton.titleLabel setFont:[UIFont fontWithName:#"Helvetica-Light" size:20]];
[myButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentRight];
[myButton setContentVerticalAlignment:UIControlContentVerticalAlignmentBottom];
[myButton setTitleColor:[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.5] forState:UIControlStateNormal];
myButton.imageView.layer.cornerRadius = 7.0f;
myButton.layer.shadowRadius = 3.0f;
myButton.layer.shadowColor = [UIColor blackColor].CGColor;
myButton.layer.shadowOffset = CGSizeMake(0.0f, 1.0f);
myButton.layer.shadowOpacity = 0.5f;
myButton.layer.masksToBounds = NO;
[buttons addObject:myButton];
[scrollview addSubview:myButton]; }
Hope this makes sense, I have seen apps that when you scroll down each item fades onto the screen but I don't seem to be able to sort this part first!
Thanks
Try to move initialisation code into background queue and only addSubview call on main queue.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
for (int i = 0; i < imgNumbers.count; i++) {
myButton = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect buttonValue = [[btn9Locations objectAtIndex:location] CGRectValue];
myButton.frame = buttonValue;
NSString *imagePart1 = [[NSString alloc] initWithFormat:#"%#", imgNumbers[i]];
[myButton addTarget:self action:#selector(buttonClick:) forControlEvents:UIControlEventTouchDownRepeat];
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
NSURL *fileURL = [tmpDirURL URLByAppendingPathComponent:imagePart1];
NSString *imageLocation = [[NSString alloc]initWithFormat:#"%#", [fileURL path]];
UIImage * image = [UIImage imageWithContentsOfFile:imageLocation];
[myButton setBackgroundColor:[UIColor colorWithRed:0.94 green:0.39 blue:0.13 alpha:0.0]];
[myButton setBackgroundImage:image forState:UIControlStateNormal];
[myButton setTitle:[imageNames[i] uppercaseString] forState:UIControlStateNormal];
[myButton.titleLabel setFont:[UIFont fontWithName:#"Helvetica-Light" size:20]];
[myButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentRight];
[myButton setContentVerticalAlignment:UIControlContentVerticalAlignmentBottom];
[myButton setTitleColor:[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.5] forState:UIControlStateNormal];
myButton.imageView.layer.cornerRadius = 7.0f;
myButton.layer.shadowRadius = 3.0f;
myButton.layer.shadowColor = [UIColor blackColor].CGColor;
myButton.layer.shadowOffset = CGSizeMake(0.0f, 1.0f);
myButton.layer.shadowOpacity = 0.5f;
myButton.layer.masksToBounds = NO;
[buttons addObject:myButton];
dispatch_async(dispatch_get_main_queue(), ^{
[scrollview addSubview:myButton];
});
}
});
Related
I need to draw dynamic images on UIScrollView for this i use, MKHorizion menu (A subclass of Scroll view). Now i add Subview images on scrollview. Loop worked perfectly for adding subview on scrollview. Now in My parent class I need to touch scroll view for updated data. If i didn't touch then it is not showing updated data. Below is code
-(void) reloadData
{
[self deleteAlliTem];
self.itemCount = [dataSource numberOfImagesForMenu:self];
self.backgroundColor = [dataSource backgroundColorForImage:self];
UIFont *buttonFont = [UIFont boldSystemFontOfSize:15];
int buttonPadding = 0;
int tag = kButtonBaseTag;
int xPos = kLeftOffset;
for(int i = 0 ; i < self.itemCount; i ++)
{
NSLog(#"*************************************************************");
NSMutableDictionary *dictData=[dataSource horizMenuImage:self dictForItmeAtIndex:i];
NSString *title=[dictData valueForKey:#"name"] ? [dictData valueForKey:#"name"] : #"";
UIImage* imageItem= [UIImage imageWithData:[Base64 decode:[dictData valueForKey:#"img"]]];
int buttonWidth = 95;
UIButton *customButton = [UIButton buttonWithType:UIButtonTypeCustom];
[customButton setTitle:title forState:UIControlStateNormal];
customButton.titleLabel.font = buttonFont;
[customButton setBackgroundImage:[UIImage imageNamed:#"addFriendStrip.png"] forState:UIControlStateNormal];
[customButton setBackgroundImage:[UIImage imageNamed:#"addFriendStrip.png"] forState:UIControlStateSelected];
customButton.tag = tag++;
[customButton addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
customButton.frame = CGRectMake(xPos, 70, buttonWidth + buttonPadding, 25);
customButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
customButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
customButton.titleEdgeInsets =UIEdgeInsetsMake(0, 10,0, 0);
customButton.titleLabel.font = [UIFont fontWithName:#"Overlock-Bold" size:16];
[customButton setTitleColor:[UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1] forState:UIControlStateNormal];
[customButton setTitleColor:[UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1] forState:UIControlStateSelected];
UIImageView* itemImageView = [[UIImageView alloc] initWithImage:imageItem];
itemImageView.tag = 200 + customButton.tag;
[itemImageView setFrame:CGRectMake(xPos, 0, buttonWidth + buttonPadding, 95)];
[self addSubview:itemImageView];
[itemImageView release];
itemImageView = nil;
[self addSubview:customButton];
xPos += buttonWidth;
xPos += buttonPadding;
if (i != self.itemCount-1){
xPos += 2.5; //5; // Richa
}
}
self.contentSize = CGSizeMake(xPos, 95);
NSLog(#"############################################################################ - %d",[[self subviews] count]);
[self scrollRectToVisible:CGRectMake(1, 0, self.frame.size.width, self.frame.size.height) animated:YES];
}
Please Help me to sort out this. Why do i needed to touch scroll view ? Do i need to override other methods ?
Did you check it is on main thread ? may be you are using GCD Queue thats why it is not updating till touch.
just try to bring your scrollview on top.I am not getting your question correctly ,but it may help.
Let me know if it is working or not..!!!
Happy Coding.!!!!
I tried to add reflection to my icarousel. Firstly my code was like this and it was working wright.
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
UIButton* button = (UIButton *)view;
if (button == nil)
{
//no button available to recycle, so create new one
UIImage *image = [arrKitapKapaklari objectAtIndex:index];
button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0.0f, 0.0f, image.size.width, image.size.height);
[button setTitleColor:[UIColor clearColor] forState:UIControlStateNormal];
[button setBackgroundImage:image forState:UIControlStateNormal];
button.titleLabel.font = [button.titleLabel.font fontWithSize:50];
[button addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
}
//set button label
[button setTitle:[NSString stringWithFormat:#"%i", index] forState:UIControlStateNormal];
return button;
}
After changing, my code became like this:
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(ReflectionView *)view
{
UIButton* button = nil;
if (button == nil)
{
view = [[[ReflectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 150.0f, 200.0f)] autorelease];
//no button available to recycle, so create new one
UIImage *image = [arrKitapKapaklari objectAtIndex:index];
button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0.0f, 0.0f, image.size.width, image.size.height);
[button setTitleColor:[UIColor clearColor] forState:UIControlStateNormal];
[button setBackgroundImage:image forState:UIControlStateNormal];
button.titleLabel.font = [button.titleLabel.font fontWithSize:50];
[button addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
[view addSubview:button];
}
//set button label
[button setTitle:[NSString stringWithFormat:#"%i", index] forState:UIControlStateNormal];
[view update];
return view;
}
Reflection appears. But the problem is when i move the carousel view, images not flowing correctly. Sometimes another carousel view appears.
Do you have any idea what causes that?
Code should be:
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(ReflectionView *)view
{
UIButton* button = nil;
if (view == nil)
{
//no view available to recycle, so create new one
view = [[[ReflectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 150.0f, 200.0f)] autorelease];
button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = view.bounds;
[button setTitleColor:[UIColor clearColor] forState:UIControlStateNormal];
button.titleLabel.font = [button.titleLabel.font fontWithSize:50];
[button addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
button.tag = 99;
[view addSubview:button];
}
else
{
button = (UIButton *)[view viewWithTag:99];
}
//set button label
[button setTitle:[NSString stringWithFormat:#"%i", index] forState:UIControlStateNormal];
UIImage *image = [arrKitapKapaklari objectAtIndex:index];
[button setBackgroundImage:image forState:UIControlStateNormal];
[view update];
return view;
}
I use images with reflection built in them... don't need to do anything in code that way.. :p
I found my mistake. I am loading images here:
-(void) getImagesWithThread{
NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init];
//for(int i=0;i<bookCount;i++){
for(int i=0;i<bookCount;i++){
NSData * imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: [arrBookImages objectAtIndex:i]]];
UIImage *image = [[UIImage imageWithData: imageData] retain];
image = [self scaleToSize:CGSizeMake(140, 200) withImage:image];
if(image!=nil) [arrBookImages replaceObjectAtIndex:i withObject:image];
[image release]; }
[carousel reloadData];
[pool drain];
}
When i performed this in background it didn't reload correctly. İf i perform normally, it works. But i want to load them in a thread. I mean first i want to set images and replace them images from url. but i want them to appear one by one. Do you have any idea?
I have got a uipickerview which will be populated when pressing a uibutton.
This uipickerview has a uitoolbar control in the top of the uipickerview.
That tool bar has got uibuttons in it.It is working fine until i do the below thing.
I want to have that uittoolbar, on top of the uikeyboard.So I have added , that uitoolbar control as InputAccessoryView.
When i did this, the uitoolbar comes with uikeyboard.that is fine.
but when i tap on the button, which has to show the uipickerview with that toolbar and also needs to resign the toolbar.
So when tap on the button, i have resigned the uikeyboard.
the uipickerview is showing but the toolbar is not visible.
I have been trying to fix this for a long time, but really facing a tough time.
Please let me know.
- (void)viewDidLoad
{
[super viewDidLoad];
// Create an UIButton
self.btnClick = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[self.btnClick addTarget: self action:#selector(showPicker)
forControlEvents:UIControlEventTouchUpInside];
// Set frame width, height
self.btnClick.frame = CGRectMake(10, 100, 30, 30);
self.btnClick.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
[self.view addSubview:self.btnClick];
self.toolBar = [[[UIToolbar alloc] init]autorelease];
[self.toolBar sizeToFit];
self.toolBar.frame = CGRectMake(0,198, 320, 35);
self.toolBar.barStyle = UIBarStyleBlackTranslucent;
UIImage *image = [UIImage imageNamed:#"orangebuttonsmall.png"];
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
aButton.bounds = CGRectMake( 0, 0, image.size.width, 25 );
[aButton setImage:image forState:UIControlStateNormal];
[aButton addTarget:self action:#selector(pickerNumPadClicked:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *numButton = [[[UIBarButtonItem alloc] initWithCustomView:aButton]autorelease];
UIImage *aCenterimage = [UIImage imageNamed:#"button_normal.png"];
UIButton *myCenterBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[myCenterBtn setTitle:#"Poet Names" forState:UIControlStateNormal];
[myCenterBtn setBackgroundImage:aCenterimage forState:UIControlStateNormal];
myCenterBtn.frame = CGRectMake(100, 0,200,25);
myCenterBtn.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
myCenterBtn.titleLabel.font = [UIFont systemFontOfSize:10];
myCenterBtn.titleLabel.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.5];
myCenterBtn.titleLabel.shadowOffset = CGSizeMake(0, -1);
myCenterBtn.bounds = CGRectInset(myCenterBtn.bounds, -3, 2);
myCenterBtn.titleLabel.font = [UIFont boldSystemFontOfSize:13];
[myCenterBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[myCenterBtn addTarget:self action:#selector(aCenterBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *flex = [[[UIBarButtonItem alloc] initWithCustomView:myCenterBtn]autorelease];
UIImage *sendImage = [UIImage imageNamed:#"orangebuttonsmall.png"];
UIButton *Sendbutton = [UIButton buttonWithType:UIButtonTypeCustom];
Sendbutton.frame = CGRectMake(0, 0,50,25);
[Sendbutton setTitle:#"Send" forState:UIControlStateNormal];
[Sendbutton setBackgroundImage:sendImage forState:UIControlStateNormal];
Sendbutton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
Sendbutton.titleLabel.font = [UIFont systemFontOfSize:10];
Sendbutton.titleLabel.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.5];
Sendbutton.titleLabel.shadowOffset = CGSizeMake(0, -1);
Sendbutton.bounds = CGRectMake( 0, 0, 50, 25 );
Sendbutton.titleLabel.font = [UIFont boldSystemFontOfSize:13];
[Sendbutton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[Sendbutton addTarget:self action:#selector(pickerDoneClicked:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *doneButton = [[[UIBarButtonItem alloc ] initWithCustomView:Sendbutton]autorelease];
[self.toolBar setItems:[NSArray arrayWithObjects:numButton,flex, doneButton, nil]];
[self.view addSubview:self.toolBar];
self.txtView = [[UITextView alloc] init];
self.txtView.layer.cornerRadius = 15;;
self.txtView.clipsToBounds = YES;
self.txtView.frame = CGRectMake(45, 100, 274, 98);
self.txtView.layer.borderWidth = 1.0f;
self.txtView.delegate = self;
self.txtView.scrollEnabled = YES;
self.txtView.backgroundColor = [UIColor whiteColor];
self.txtView.contentInset = UIEdgeInsetsZero;
self.txtView.returnKeyType = UIReturnKeyDone; // type of the return key
self.txtView.layer.borderColor = [[UIColor blueColor] CGColor];
self.txtView.font = [UIFont fontWithName:#"Helvetica" size:17.0f];
[self.txtView setInputAccessoryView:self.toolBar];
[self.view addSubview:self.txtView];
self.itemsArray = [[[NSArray alloc]initWithObjects:#"William Langland",#"Philip Larkin", #"Dorianne Laux", #"David Lehman", #"Denise Levertov", nil]autorelease];
}
-(void)showPicker
{
[self.txtView resignFirstResponder];
self.pickerView = [[[UIPickerView alloc]init]autorelease];
self.pickerView.showsSelectionIndicator = YES;
self.pickerView.dataSource = self;
self.pickerView.delegate = self;
self.pickerView.tag = 0;
self.pickerView.autoresizingMask = (UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight);
[self.pickerView sizeToFit];
self.pickerView.frame = CGRectMake(0, 293 , 320, 15);
self.toolBar.frame = CGRectMake(0,253, 320, 35);
[self.view addSubview:self.toolBar];
[self.view addSubview:self.pickerView];
[self.pickerView selectRow:1 inComponent:0 animated:YES];
}
Try this link
http://blog.swierczynski.net/2010/12/how-to-create-uipickerview-with-toolbar-above-it-in-ios/
It shows how to put a inputAccessoryView on uipicker
I have a demo working but I was wondering if there is already a library like Three20 that comes with this sort of control.
This is what I have till now. It's not refactored yet.
-
(void)viewDidLoad {
[super viewDidLoad];
// Gets Types
[self getTypes];
// Set Guilt Types UI
CGFloat kTopMargin = 160.0;
CGFloat kTopMarginSpan = 30.0;
NSEnumerator *enumerator = [TypesArray objectEnumerator];
id obj;
while ( obj = [enumerator nextObject] ) {
CGSize fontSize = [[obj name] sizeWithFont:[UIFont systemFontOfSize:22.0]];
UILabel *aLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, kTopMargin, fontSize.width, 25.0)];
aLabel.font = [UIFont fontWithName:#"Helvetica" size:22.0];
aLabel.adjustsFontSizeToFitWidth = YES;
aLabel.highlightedTextColor = [UIColor blackColor];
aLabel.textAlignment = UITextAlignmentCenter;
aLabel.textColor = [UIColor colorWithRed:168/255.0 green:16/255.0 blue:16/255.0 alpha:1.0];
aLabel.backgroundColor = [UIColor clearColor];
aLabel.text = [obj name];
[self.view addSubview:aLabel];
[aLabel release];
UIButton *aButton = [[UIButton alloc] initWithFrame:CGRectMake(fontSize.width + 10.0, kTopMargin + 5, 16.0, 16.0)];
[aButton setBackgroundImage:[[UIImage imageNamed:#"checkbox.png"] stretchableImageWithLeftCapWidth: 12.0 topCapHeight: 0.0] forState:UIControlStateNormal];
[aButton setBackgroundImage:[[UIImage imageNamed:#"chechbox-checked.png"] stretchableImageWithLeftCapWidth: 12.0 topCapHeight: 0.0] forState:UIControlStateSelected];
[aButton setBackgroundImage:[[UIImage imageNamed:#"chechbox-pressed.png"] stretchableImageWithLeftCapWidth: 12.0 topCapHeight: 0.0] forState:UIControlStateHighlighted];
[aButton setBackgroundColor:[UIColor clearColor]];
aButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
aButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
[self.view addSubview:aButton];
[aButton release];
kTopMargin = kTopMargin + kTopMarginSpan;
}
}
A UITableView with cells that have their accessoryType set to UITableViewCellAccessoryCheckmark is the iPhone standard for this style
i have implemented the following code in my project!
UIImage *add_item_icon = [UIImage imageNamed:#"add_item_icon.png"];
UIImage *img = [UIImage imageNamed:#"add_button.png"];
if(headerButton != nil)
[headerButton release];
headerButton = [[UIButton alloc] init];
headerButton.frame = CGRectMake(0, 0, 320, 42);
headerButton.backgroundColor = [UIColor clearColor];
headerButton.showsTouchWhenHighlighted = YES;
[headerButton setBackgroundImage:img forState:UIControlStateNormal];
[headerButton setTitle:#"Add New Gallery" forState:UIControlStateNormal];
[headerButton setImage:add_item_icon forState:UIControlStateNormal];
headerButton.titleLabel.font = [UIFont systemFontOfSize:16];
headerButton.titleLabel.textColor = [UIColor darkGrayColor];
[headerButton addTarget:self action:#selector(headerButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
//[headerButton setTitleColor:[UIColor darkGrayColor] forState:UIControlStateSelected];
My question is whenever i click the button, the color which is assigned to the title has been changed. The requirement is it should not be like that. Any one pls guide me! as early possible.
Not sure what is in your -headerButtonClicked:, but you should remove anything that looks like this in -headerButtonClicked:
headerButton.titleLabel.textColor = [UIColor darkGrayColor];