I am creating 5 UIButtons, using a for loop, and would like to put 5 different avatars on the UIButtons. However, only one avatar is filling all 5 buttons.
The code I have constructed looks like the following,
// create a subview for avatar buttons
UIView *avatarView = [[UIView alloc] init];
avatarView.frame = CGRectMake(20, 125, 280, 100); // don't mess with these values.
// avatarView.layer.borderColor = [UIColor redColor].CGColor;
// avatarView.layer.borderWidth = 3.0f;
[self.view addSubview:avatarView];
UIScrollView *avatarScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0, self.view.frame.size.width, self.view.frame.size.height)];
avatarScroll.contentSize = CGSizeMake(500, 500);
avatarScroll.scrollEnabled = YES;
[avatarView addSubview:avatarScroll];
// fetch Data from Core Data
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Account" inManagedObjectContext:_managedObjectContext];
[fetchRequest setEntity:entity];
// fetch records and handle error
NSError *error;
NSArray *results = [_managedObjectContext executeFetchRequest:fetchRequest error:&error];
// sort results array by lastLogin
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:#"lastLogin" ascending:NO];
NSArray *sortedArray = [NSArray arrayWithObject:sort];
NSArray *sortedArray2 = [results sortedArrayUsingDescriptors:sortedArray];
// how to remove values from NSArray
NSArray *lastLoginArray = [sortedArray2 valueForKey:#"lastLogin"];
// NSLog(#"lastLoginArray = %#",lastLoginArray);
// make an array that only hold 5 values
// NSArray *last5LoginArray;
// for (int i=5; i<[lastLoginArray count]; i++) {
// [last5LoginArray addObject:[lastLoginArray objectAtIndex:i]];
// }
// NSLog(#"last5LoginArray = %#",last5LoginArray);
// NSArray *last5LoginArray = [NSArray arrayWithObjects:lastLoginArray count:4];
// NSArray *last5LoginArray = [NSArray arrayByAddingObjectsFromArray:lastLoginArray count:4];
NSMutableArray *last5LoginArray = [[NSMutableArray alloc] initWithArray:[lastLoginArray subarrayWithRange:NSMakeRange(0, 5)] ];
NSLog(#"last5LoginArray = %#",last5LoginArray);
// NSLog(#"sortedArray2 = %#",sortedArray2);
CGFloat staticX = 0;
CGFloat staticWidth = 80;
CGFloat staticHeight = 80;
CGFloat staticPadding = 5;
// need to put the avatars stored in sortedArray2 in the scrollView
for ( int i = 0; i < 5; i++) {
// do additional loading for avatars
UIButton *avatarButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
// the last two values control the size of the button
// avatarButton.frame = CGRectMake(0, 0, 80, 80);
[avatarButton setFrame:CGRectMake((staticX + (i * (staticHeight + staticPadding))),5,staticWidth,staticHeight)];
// make corners round
avatarButton.layer.cornerRadius = 40; // value varies -- // 35 yields a pretty good circle.
avatarButton.clipsToBounds = YES;
// create a stock image
UIImage *btnImage = [UIImage imageNamed:#"HomeBrewPoster1.jpg"];
Account *anAccount;
for ( anAccount in results) {
if([last5LoginArray containsObject:anAccount.lastLogin]) {
NSLog(#"anAccount.lastLogin = %#",anAccount.lastLogin);
UIImage *avatarImg = [UIImage imageWithData:anAccount.avatar ];
// apply avImg to btn
[avatarButton setBackgroundImage:avatarImg forState:UIControlStateNormal];
}
}
if (btnImage == nil) {
NSLog(#"can't find HomeBrewPoster1.jpg");
// apply stock image to button(s)
[avatarButton setBackgroundImage:btnImage forState:UIControlStateNormal];
} else {
}
// this should add 5x buttons
[avatarScroll addSubview:avatarButton];
}
Your innermost for-in loop always sets the last matching avatar to the button, because the current value of i makes absolutely no difference to what the innermost loop does.
You should move the nested loop outside the first loop to prepare the five avatars upfront, and then use i to index into the array of avatars, like this:
NSMutableArray *avatars = [NSMutableArray arrayWithCapacity:5];
for ( anAccount in results) {
if([last5LoginArray containsObject:anAccount.lastLogin]) {
NSLog(#"anAccount.lastLogin = %#",anAccount.lastLogin);
UIImage *avatarImg = [UIImage imageWithData:anAccount.avatar ];
[avatars addObject:avatarImg];
}
}
NSAssert(
avatars.count == last5LoginArray.count
, #"The loop is expected to find as many avatars as there are items in last5LoginArray"
);
for ( int i = 0; i < 5; i++) {
...
// Check that we have enough logins
if (i < last5LoginArray.count) {
[avatarButton setBackgroundImage:avatars[i] forState:UIControlStateNormal];
}
}
Declare button as an array
NSArray *arrImages = [NSArray arrayWithObjects:#"1.jpg",#"2.jpg",#"3.jpg",#"4.jpg",#"5.jpg", nil];
UIButton *button[5];
button[i] = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button[i] addTarget:self action:#selector(aMethod:) forControlEvents:UIControlEventTouchUpInside];
[button[i] setBackgroundImage:[UIImage imageNamed:[arrImages objectAtIndex:i]] forState:UIControlStateNormal];
[button[i] setTitle:#"Title" forState:UIControlStateNormal];
button[i].frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[avatarScroll addSubview:button[i]];
You can name your images like "HomeBrewPoster0", "HomeBrewPoster1", etc. And add this to choose right image in your loop:
UIImage *btnImage = [UIImage imageNamed:[NSString stringWithFormat:#"HomeBrewPoster%ld.jpg", i]];
Related
There is part of my Json,
{
pontos = (
{
Id = 1;
Latitude = "-22.739";
Longitude = "-47.335";
cidade = Americana;
endereco = "RUA WASHINGTON LUIZ, 742, CENTRO, Americana/SP";
letra = "letter-A";
localizacao = "https://www.google.com.br/maps/dir//Quinoa+Natural+-+Washington+Luiz,+742+-+Centro,+Americana+-+SP,+13465-520/#-22.7399455,-47.3349734,19.5z/data=!4m15!1m6!3m5!1s0x0:0xa4eca82f1081bbd9!2sQuinoa+Natural!8m2!3d-22.739908!4d-47.3353712!4m7!1m0!1m5!1m1!1s0x94";
nome = "QUINOA NATURAL";
site = "WWW.QUINOANATURAL.COM.BR";
telefone = "(19) 3405-6006";
},
{
Id = 2;
Latitude = "-22.752";
Longitude = "-47.345";
cidade = Americana;
endereco = "AV. BRASIL, 1740, VILA FREZZARIN, Americana/SP";
letra = "letter-A";
localizacao = "https://www.google.com.br/maps/dir//Av.+Brasil+Norte,+1740+-+Vila+Frezzarin,+Americana+-+SP/#-22.7522934,-47.3479628,17z/data=!4m13!1m4!3m3!1s0x94c89bd929bbb37d:0x97700c95cf048c5d!2sAv.+Brasil+Norte,+1740+-+Vila+Frezzarin,+Americana+-+SP!3b1!4m7!1m0!1m5!1";
nome = "TERRANUTRA ORG\U00c2NICOS";
site = "";
telefone = "(19) 3408-0032";
},
Here is my code
- (void)viewDidLoad
{
int test = 40;
UIScrollView *sView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 350, 460)];
[self.view addSubview:sView];
//http://blessing.com.br/aplicativos/pontos.php
//http://api.iospond.com/api/index.php/GetData
//setting the json as data
NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://blessing.com.br/aplicativos/pontos.php"]];
NSError *error=nil;
//Encoding the data to string
NSString *teste = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
//show the code json
//putting the json in an arraylist
NSArray *json = [NSJSONSerialization JSONObjectWithData:[teste dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error ];
CGFloat xPos = 0;
CGFloat x = 0;
CGFloat y = 10;
CGFloat yPos = 10;
for (NSDictionary *dic in json) {
//show Ids catched in the json
NSLog(#"%#", dic);
//show names catched uin the json
//set the ids of json as number of button.tag
int numberOfButtons = [dic[#"id"] integerValue];
// show number of button.tag
if(xPos == 170){
NSMutableArray *mutableArray = [[NSMutableArray alloc] init];
yPos +=20;
//create a button
self.button = [UIButton alloc];
self.button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.button.frame = CGRectMake(xPos, yPos, 40, 20);
button.tag = numberOfButtons;
//set the button title for the normal state
[self.button setTitle:[dic objectForKey:#"id"] forState:UIControlStateNormal];
//set the button title for when the finger is pressing it down
[self.button setTitle:[dic objectForKey:#"name"] forState:UIControlStateHighlighted];
//add action to capture the button press down event
[self.button addTarget:self action:#selector(buttonIsPressed:)forControlEvents:UIControlEventTouchDown];
//add the button to the view
[sView addSubview:self.button];
//Button Styles
yPos += 10;
test = 50 + yPos;
//Add the button into array
[mutableArray addObject:button];
//show code button
xPos = 0;
x = 10;
}
if(x == 0){
NSMutableArray *mutableArray = [[NSMutableArray alloc] init];
//adding 10 to change the location of the next button that will be create
y +=20;
//create a button
self.button = [UIButton alloc];
self.button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.button.frame = CGRectMake(x, y, 40, 20);
button.tag = numberOfButtons;
//set the button title for the normal state
[self.button setTitle:[dic objectForKey:#"id"] forState:UIControlStateNormal];
//set the button title for when the finger is pressing it down
[self.button setTitle:[dic objectForKey:#"name"] forState:UIControlStateHighlighted];
//add action to capture the button press down event
[self.button addTarget:self action:#selector(buttonIsPressed:)forControlEvents:UIControlEventTouchDown];
//add the button to the view
[sView addSubview:self.button];
//Button Styles
y += 10;
//Add the button into array
[mutableArray addObject:button];
//show code button
//NSLog(#"%#", mutableArray);
xPos = 170;
}
if (x == 10) {
x = 0;
}
CGSize sViewContentSize = CGSizeMake(320, test);
[sView setContentSize:sViewContentSize];
//NSLog(#"%i", test);
}
}
And here is the Log
2017-05-11 10:08:16.589 tentativaJSON[4082:90b] pontos
So I want catch the Details of pontos but it is showing only it, i need use the values of Id`s and the other informations inside it to do buttons related to it, using this //http://api.iospond.com/api/index.php/GetData I don't get any problem, but if I'm using this //http://blessing.com.br/aplicativos/pontos.php I get this error Thread 1: signal SIGABRT, someone can help with it?
You should use GET :-
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:[NSString
stringWithFormat:#"http://api.iospond.com/api/index.php/GetData"]]];
[request setHTTPMethod:#"GET"];
[request setTimeoutInterval:60];
[NSURLConnection sendAsynchronousRequest:request queue:
[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response,
NSData *data, NSError *error) {NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
if ([(NSHTTPURLResponse *)response
statusCode] == 200) {
NSArray *dict = (NSArray *)str;
NSLog(#"Parse here:: %#",dict);
}else {
NSLog(#"elseelse
%#",error.localizedDescription);
}
}];
Then check you getting array or Dictionary for parsing step by step..
NSDictionary *dic in json
will only give you the keys.
To get their values use
json[dic]
Does anyone know why is appearing white part? My View is already gray, but gets two white pieces
whites: Arrow and final Popover!
[UPDATE]
this is the code that calls the popover and makes the arrow points to the button that was clicked!
- (void) buttonFilter {
if (viewFilter == #"Artistas") {
content = [self.storyboard instantiateViewControllerWithIdentifier:#"TipoArtistaViewController"]; // MUDAR PARA O NOVO FILTRO DE ARTISTAS
} else if (viewFilter == #"Músicas") {
content = [self.storyboard instantiateViewControllerWithIdentifier:#"CategoriaViewController"];
}
[self callFilter:btnFilter Filter:content];
}
- (void)callFilter:(id)sender Filter:(UIViewController *) content{
self.currentPop = popoverController;
popoverController = [[WYPopoverController alloc] initWithContentViewController:content];
UIButton * bt = (UIButton * )sender;
UIView *view = [bt valueForKey:#"view"];
popoverController.popoverContentSize = CGSizeMake(320, 180);
popoverController.delegate = self;
[popoverController presentPopoverFromRect:view.bounds inView:view permittedArrowDirections:WYPopoverArrowDirectionAny animated:YES];
}
the next is where to mount the session:
//extend and collpase
- (void)setupViewController {
categoriaBD = [categoriaDAO selectCategoria];
self.data = [[NSMutableArray alloc] init];
for (int i = 0; i < [categoriaBD count]; i++)
{
NSMutableDictionary * teste = [categoriaBD objectForKey:[NSString stringWithFormat:#"%i", i]];
ID = [[teste objectForKey:#"1"] integerValue];
subcategoriaBD = [categoriaDAO selectSubCategoriaByCategoriaID:ID];
NSMutableArray* section = [[NSMutableArray alloc] init];
for (int j = 0; j < [subcategoriaBD count]; j++)
{
NSMutableDictionary * subCat = [subcategoriaBD objectForKey:[NSString stringWithFormat:#"%i", j]];
[section addObject:[NSString stringWithFormat:[subCat objectForKey:#"1"]]];
}
[self.data addObject:section];
}
self.headers = [[NSMutableArray alloc] init];
for (int i = 0; i < [categoriaBD count]; i++)
{
NSString *inStr = [NSString stringWithFormat: #"%i", (int)i];
nomeCategoria = [categoriaBD objectForKey:inStr];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(5, 5, 310, 40)];
[label setText:[nomeCategoria objectForKey:#"2"]];
UIView* header = [[UIView alloc] init];
[header setBackgroundColor:[UIColor colorWithRed:(226/255.0) green:(226/255.0) blue:(226/255.0) alpha:1]];
[header addSubview:label];
[self.headers addObject:header];
}
}
You can to create a custom UIPopoverBackgroundView subclass that sets the properties of the arrow you want.
popoverController.popoverBackgroundViewClass = [MyPopoverBackgroundView class];
I am trying to show no. of images in different image view. if i have 3 image then i want show in 3 diff. UIImageView in my View. Here is my code that only shows one image. What have i missed here?
NSArray * _thumbnails = _claimReport.photos.allObjects;
if (_thumbnails.count >0)
{
NSMutableArray *imageViews = [[NSMutableArray alloc] init];
for (int i =1; i<_thumbnails.count; i++)
{
UIImageView *newImageViews = [[UIImageView alloc]initWithFrame:CGRectMake(40, 1700*i+20, 670, 700)];
LAPhoto *photo = [_thumbnails objectAtIndex:i];
[newImageViews setImage:[UIImage imageWithData:photo.photo]];
NSLog(#" newImageViews %# ",newImageViews);
[imageViews addObject:newImageViews];
[self.formView addSubview:newImageViews];
}
NSLog(#"Count %d" , imageViews.count);
}
You can add the images in a scroll view:
self.scrollView = [[UIScrollView alloc]initWithFrame:self.view.bounds];
[self.formView addSubview:self.scrollView];
NSArray * _thumbnails = _claimReport.photos.allObjects;
if (_thumbnails.count >0)
{
NSMutableArray *imageViews = [[NSMutableArray alloc] init];
for (int i =0; i<_thumbnails.count; i++)
{
UIImageView *newImageViews = [[UIImageView alloc]initWithFrame:CGRectMake(40, 800*i+20, 670, 700)];
LAPhoto *photo = [_thumbnails objectAtIndex:i];
[newImageViews setImage:[UIImage imageWithData:photo.photo]];
NSLog(#" newImageViews %# ",newImageViews);
[imageViews addObject:newImageViews];
self.scrollView.contentSize = CGSizeMake(670, 800 *i + 800);
[self.scrollView addSubview:newImageViews];
}
NSLog(#"Count %d" , imageViews.count);
}
Now I create is as follow (my file.h):
UIImageView *pic1, *pic2, *pic3, *pic4, *pic5, *pic6, *pic7, *pic8, *pic9, *pic10;
Then in my (file.m):
UIImageView *pic1 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#”picName.png”]];
UIImageView *pic2 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#”picName.png”]];
……
UIImageView *pic10 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#”picName.png”]];
I need many instances of UIImageView (number triggered by other factors) of only one in this case picture.
Is there any way to create multiple instances of UIImageView automatically in my file.m, somehow as follow?:
for (int x; (x=10); x++)
{
UIImageView * pic[x] = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"myPic.png"]];
}
This example doesn’t work but I’d like to show what I want to program.
Of course you can - that is what the arrays are for:
NSMutableArray *pics = [NSMutableArray array];
for (int i = 0 ; i != 10 ; i++) {
[pics addObject:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"myPic.png"]]];
}
In case the name of the picture depends on the index, use NSString's stringWithFormat to produce the name of the picture - for example, you can do it like this:
NSMutableArray *pics = [NSMutableArray array];
for (int i = 0 ; i != 10 ; i++) {
NSString *imgName = [NSString stringWithFormat:#"myPic%d.png"];
[pics addObject:[[UIImageView alloc] initWithImage:[UIImage imageNamed:imgName]]];
}
If the names of images follow a standard pattern you can just loop over the required amount and build the image name dynamically using the index.
If the names of the images do not follow a standard patten you can chuck them in an array and loop over them
NSArray *imageNames = #[
#"alarm.jpg",
#"bell.jpg",
#"car.jpg"
];
NSMutableArray *imageViews = [[NSMutableArray alloc] init];
for (NSString *imageName in imageNames) {
[imagesViews addObject:({
[[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]];
})];
}
Completely optional - further reading
You could write yourself a simple category that abstracts this looping and collecting the results into a new array. This would allow you to simply write
NSArray *imageNames = #[
#"alarm.jpg",
#"bell.jpg",
#"car.jpg"
];
NSArray *imageViews = [imageNames pas_arrayByMappingWithBlock:^(id obj){
return [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]];
}];
The category to do that would look something like this:
#interface NSArray (PASAdditions)
- (NSArray *)pas_arrayByMappingWithBlock:(id (^)(id obj))block
#end
#implementation NSArray (PASAdditions)
- (NSArray *)pas_arrayByMappingWithBlock:(id (^)(id obj))block
{
NSMutableArray *result = [[NSMutableArray alloc] init];
for (id obj in self) {
[result addObject:block(obj)];
}
return [result copy];
}
#end
I have 20 images in my main bundle and i want to display it in my scroll view horizontally.
I am doing it successfully but now the problem is images are visible in scrollview after all imageview are set in scroll view and it takes time.
For resolve that I create one nsoperation.
-(BOOL)sync:(NSError**)error
{
float imageLeftPosition = 0;
for (int imageCount = 1; imageCount<=syncObject.syncNumberOfImages; imageCount++) {
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(imageLeftPosition, 0, syncObject.syncImageWidth, syncObject.syncImageHeight)];
[imgView setImage:[UIImage imageNamed:[NSString stringWithFormat:#"%d_%d.jpg",syncObject.syncChapterNumber,imageCount]]];
imgView.tag = imageCount;
// NSDictionary *dictionary = [NSDictionary new];
//
// [dictionary setValue:imgView forKey:CHAPTER_IMAGE];
imageLeftPosition = imageLeftPosition+syncObject.syncImageWidth;
//[dictionary setValue:[NSString stringWithFormat:#"%f",imageLeftPosition] forKey:CHAPTER_SCROLL_LEFT_POSITION];
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:imgView,[NSString stringWithFormat:#"%f",imageLeftPosition], nil] forKeys:[NSArray arrayWithObjects:CHAPTER_IMAGE,CHAPTER_SCROLL_LEFT_POSITION, nil]];
[self sendNotification:dictionary];
imgView = nil;
dictionary = nil;
}
return YES;
}
what i am doing here is add create one image view and post it to main view using notification
-(void)addImageView:(NSNotification*)notification
{
NSInteger thread = [NSThread isMainThread]?CVC_MainThread:CVC_BackgroundThread;
switch (thread) {
case CVC_MainThread:
{
NSDictionary *dictionary = notification.userInfo;
if(dictionary != nil)
{
NSLog(#"image view : %#",(UIImageView*)[dictionary valueForKey:CHAPTER_IMAGE]);
NSLog(#"leftposition: %f",[[dictionary valueForKey:CHAPTER_SCROLL_LEFT_POSITION] floatValue]);
[_scrChapters addSubview:((UIImageView*)[dictionary valueForKey:CHAPTER_IMAGE])];
_scrChapters.contentSize = CGSizeMake([[dictionary valueForKey:CHAPTER_SCROLL_LEFT_POSITION] floatValue], 0);
}
dictionary = nil;
}
break;
case CVC_BackgroundThread:
{
dispatch_async(dispatch_get_main_queue(), ^(void) {
NSDictionary *dictionary = notification.userInfo;
if(dictionary != nil)
{
NSLog(#"image view : %#",(UIImageView*)[dictionary valueForKey:CHAPTER_IMAGE]);
NSLog(#"leftposition: %f",[[dictionary valueForKey:CHAPTER_SCROLL_LEFT_POSITION] floatValue]);
[_scrChapters addSubview:((UIImageView*)[dictionary valueForKey:CHAPTER_IMAGE])];
_scrChapters.contentSize = CGSizeMake([[dictionary valueForKey:CHAPTER_SCROLL_LEFT_POSITION] floatValue], 0);
}
dictionary = nil;
});
}
break;
default:
break;
}
}
this is the notification handler method where i set the content size and image view in scroll view for each loop on main thread still scroll view are visible after all the images are load.
What I am doing wrong?
Try to use pagedflowview. This will load only the visible items into the Scrollview and is easy to customize. You can also search for iCarousel.
https://www.cocoacontrols.com/controls/pagedflowview
Try this
-(void)showimagesasSlide:(int) totalimagesCount
{
int xAxisofimageView=0;
for (int initialimagesCount=0;initialimagesCount<totalimagesCount; initialimagesCount++) {
UIImageView *detailedImageview=[[UIImageView alloc] init];
detailedImageview.userInteractionEnabled=YES;
UIImage *dynamicImage=[ScaleImageSize squareImageWithImage:[images objectAtIndex:initialimagesCount] scaledToSize:CGSizeMake(300, 500) ];
if (IS_IPHONE_5) {
detailedImageview.frame=CGRectMake(xAxisofimageView, 0, 320, 568);
}
else
{
detailedImageview.frame=CGRectMake(xAxisofimageView, 0, 320, 460);
}
// detailedImageview.contentMode=UIViewContentModeCenter;
detailedImageview.backgroundColor=[UIColor clearColor];
detailedImageview.image=dynamicImage;
detailedImageview.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin ;
detailedImageview.tag=initialimagesCount+12;
[mainScrollview addSubview:detailedImageview];
xAxisofimageView=xAxisofimageView+320;
}
mainScrollview.contentSize=CGSizeMake(320*images.count, 0);
}