Have a problem with my MutableArray. I've the data array in my tableview, and everything is ok, but when the data is sorting by a distance and i'm choosing an item in cell, it shows me incorrect data in new viewcontroller. It shows the data without sorting. It's like a broken link) Hope for your help)
i'm new in obj-c, so i apologise)
here is my code:
list = [[NSMutableArray alloc] init];
[list addObject:#{#"name": #"Central office", #"address":#"наб. Обводного канала, д.66А", #"phone":#"+7 (812) 320-56-21 (многоканальный)", #"workTime":#"ПН-ПТ: с 9:30 до 18:30", #"email":#"mail#ibins.ru", #"payment":#"Принимаются к оплате пластиковые карты VISA и MasterCard", #"longitude":#30.336842, #"latitude":#59.913950}];
[list addObject:#{#"name": #"Second office", #"address":#"ул. Камышовая, д.38", #"phone":#"+7 (812) 992-992-6; +7 (812) 456-26-43", #"workTime":#"Ежедневно: с 9:30 до 20:00", #"email":#"sever#ibins.ru", #"payment":#"Принимаются к оплате пластиковые карты VISA и MasterCard", #"longitude":#30.219863, #"latitude":#60.008805}];
[list addObject:#{#"name": #"Third office", #"address":#"Street name", #"phone":#"phone number", #"workTime":#"Work time", #"email":#"email address", #"longitude":#30.294254, #"latitude":#60.028728}];
[self constructList];
[self constructPins];
}
- (IBAction)switchDisplayType:(id)sender {
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:0.80];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:NO];
[UIView commitAnimations];
if ([(UISegmentedControl*)sender selectedSegmentIndex] == 1) {
map.hidden = YES;
contentSV.hidden = NO;
}
else {
map.hidden = NO;
contentSV.hidden = YES;
}
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
static NSString* BridgeAnnotationIdentifier = #"bridgeAnnotationIdentifier";
MKPinAnnotationView* customPinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:BridgeAnnotationIdentifier] autorelease];
customPinView.pinColor = MKPinAnnotationColorRed;
customPinView.animatesDrop = YES;
customPinView.canShowCallout = YES;
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
// NSLog(#"%#",rightButton);
[rightButton addTarget:self
action:#selector(annotationButtonTapped:)
forControlEvents:UIControlEventTouchUpInside];
customPinView.rightCalloutAccessoryView = rightButton;
return customPinView;//[kml viewForAnnotation:annotation];
}
- (void)annotationButtonTapped:(id)sender {
DetailVC *sampleVC = [[DetailVC alloc] initWithNibName:#"DetailVC" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:sampleVC animated:YES];
[sampleVC release];
for (NSDictionary *dict in list) {
if ([[dict valueForKey:#"name"] isEqualToString:selectedAnnTitle]) {
[sampleVC updateViewWithDict:dict];
}
}
}
- (void)constructPins {
for (NSDictionary *dict in list) {
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = 0.3;
span.longitudeDelta = 0.3;
CLLocationCoordinate2D location;
location.latitude = [[dict valueForKey:#"latitude"] floatValue];
location.longitude = [[dict valueForKey:#"longitude"] floatValue];
if (location.latitude == 0.0 && location.longitude == 0.0)
return;
region.span = span;
region.center = location;
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = location;
point.title = [dict valueForKey:#"name"];
[map addAnnotation:point];
[map setRegion:region animated:YES];
}
}
- (void)constructList {
int n = 0;
for (NSDictionary *dict in list) {
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 100*n, 320, 100)];
container.backgroundColor = [UIColor whiteColor];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 320, 100)];
button.tag = n;
[button addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
[container addSubview:button];
NSString *str = [NSString stringWithFormat:#"%#\nAddress: %#\nPhone: %#\nWork Time: %#", [dict valueForKey:#"name"], [dict valueForKey:#"address"], [dict valueForKey:#"phone"], [dict valueForKey:#"workTime"]];
UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 300, 80)];
nameLabel.textAlignment = NSTextAlignmentLeft;
nameLabel.numberOfLines = 0;
nameLabel.text = str;
nameLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:12.0];
[container addSubview:nameLabel];
UIView *separator = [[UIView alloc]initWithFrame:CGRectMake(0, 99, 320, 1)];
separator.backgroundColor = [UIColor darkGrayColor];
[container addSubview:separator];
[contentSV addSubview:container];
n++;
contentSV.contentSize = CGSizeMake(0, 100*n);
}
}
- (float)distanceBetweenLat1:(float)tlat1 lon1:(float)tlon1 lat2:(float)tlat2 lon2:(float)tlon2 {
float result = 0.0;
int R = 6371;
float currentLatitude = tlat1;
float currentLongtitude = tlon1;
float lat2 = tlat2;
float lon2 = tlon2;
float dLat = (lat2-currentLatitude)*M_PI/180;
float dLon = (lon2-currentLongtitude)*M_PI/180;
float nlLat = currentLatitude*M_PI/180;
lat2 = lat2*M_PI/180;
float a = sin(dLat/2) * sin(dLat/2) + sin(dLon/2) * sin(dLon/2) * cos(nlLat) * cos(lat2);
float c = 2 * atan2(sqrt(a), sqrt(1-a));
result = R * c;
return result;
}
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
selectedAnnTitle = [view.annotation title];
return;
DetailVC *sampleVC = [[DetailVC alloc] initWithNibName:#"DetailVC" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:sampleVC animated:YES];
NSString *ttl = [view.annotation title];
for (NSDictionary *dict in list) {
if ([[dict valueForKey:#"name"] isEqualToString:ttl]) {
[sampleVC updateViewWithDict:dict];
}
}
[map deselectAnnotation:view.annotation animated:NO];
}
- (void)buttonTapped:(id)sender {
DetailVC *sampleVC = [[DetailVC alloc] initWithNibName:#"DetailVC" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:sampleVC animated:YES];
int n = 0;
for (NSDictionary *dict in list) {
if (n == [sender tag]) {
[sampleVC updateViewWithDict:dict];
}
n++;
}
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
NSLog(#"didUpdateUserLocation");
MKAnnotationView* annotationView = [mapView viewForAnnotation:userLocation];
annotationView.canShowCallout = NO;
if (!userLocationUpdated) {
if (userLocation.coordinate.latitude > 0.1 && userLocation.coordinate.longitude > 0.1) {
// NSLog(#"SORT BY DISTANCE");
userLocationUpdated = YES;
for (int i = 0; i < [list count]; i++) {
NSMutableDictionary *record = [[NSMutableDictionary alloc] initWithDictionary:[list objectAtIndex:i]];
float latitude = [[record valueForKey:#"latitude"] floatValue];
float longitude = [[record valueForKey:#"longitude"] floatValue];
float dist = [self distanceBetweenLat1:map.userLocation.coordinate.latitude lon1:map.userLocation.coordinate.longitude lat2:latitude lon2:longitude];
NSNumber *distN = [NSNumber numberWithFloat:dist];
[record setObject:distN forKey:#"distance"];
[list replaceObjectAtIndex:i withObject:record];
}
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"distance" ascending:YES];
NSArray *itemsListSorted = [[NSArray alloc] initWithArray:list];
itemsListSorted = [itemsListSorted sortedArrayUsingDescriptors:[NSArray arrayWithObjects:descriptor,nil]];
for (UIView *view in contentSV.subviews) {
[view removeFromSuperview];
}
for (int i = 0; i < [itemsListSorted count]; i++) {
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 100*i, 320, 100)];
container.backgroundColor = [UIColor whiteColor];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 320, 100)];
button.tag = i;
[button addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
[container addSubview:button];
NSString *str = [NSString stringWithFormat:#"%#\nAddress: %#\nPhone: %#\nWorkTime: %#", [[itemsListSorted objectAtIndex:i] valueForKey:#"name"], [[itemsListSorted objectAtIndex:i] valueForKey:#"address"], [[itemsListSorted objectAtIndex:i] valueForKey:#"phone"], [[itemsListSorted objectAtIndex:i] valueForKey:#"workTime"]];
UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 300, 80)];
nameLabel.textAlignment = NSTextAlignmentLeft;
nameLabel.numberOfLines = 0;
nameLabel.text = str;
nameLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:12.0];
[container addSubview:nameLabel];
UILabel *distanceLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 2, 300, 21)];
distanceLabel.textAlignment = NSTextAlignmentRight;
distanceLabel.text = [NSString stringWithFormat:#"%.1f км", [[[itemsListSorted objectAtIndex:i] valueForKey:#"distance"] floatValue]];
distanceLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:12.0];
distanceLabel.textColor = [UIColor lightGrayColor];
[container addSubview:distanceLabel];
UIView *separator = [[UIView alloc]initWithFrame:CGRectMake(0, 99, 320, 1)];
separator.backgroundColor = [UIColor darkGrayColor];
[container addSubview:separator];
[contentSV addSubview:container];
contentSV.contentSize = CGSizeMake(0, 100*(i+1));
}
}
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#end
Although there are numerous issues with this code (the least of which are some minor precision issues with the distance calculation), the problem is not with the distance calculation.
The detail view controller shows incorrect data because it is given the data from the list array which is not itself sorted by distance.
In the didUpdateUserLocation delegate method, the contents of list are copied to a local array named itemsListSorted.
Only the itemsListSorted array is sorted by distance and then the display is updated using this local array.
But the original list array (which the buttonTapped method uses as the source of the data to send to the detail view controller) is never updated.
So if "Central Office" is at index 0 in list but gets moved to index 2 in itemsListSorted, the display shows the correct position but when you tap on it, the buttonTapped method sends the item at index 2 from the list array which does not have "Central Office" (it's still at index 0 in list).
One way to fix this problem is to stop using a local array and sort the list array directly.
In didUpdateUserLocation, you could replace these two lines:
NSArray *itemsListSorted = [[NSArray alloc] initWithArray:list];
itemsListSorted = [itemsListSorted sortedArrayUsingDescriptors:[NSArray arrayWithObjects:descriptor,nil]];
with this:
[list sortUsingDescriptors:[NSArray arrayWithObjects:descriptor,nil]];
and then replace all references to itemsListSorted in the same method with list.
Regarding the other issues with the code, there is not enough room to point them all out or explain them in one answer. However, here are just a few highlights:
Instead of a manually creating a "table view", use an actual UITableView.
Instead of manually calculating distance between coordinates, use the distanceFromLocation method in the CLLocation class or the MKMetersBetweenMapPoints function.
In viewForAnnotation, you should return nil if annotation is of type MKUserLocation otherwise it will appear as a red pin just like the others.
Use ARC instead of manual memory management.
Related
I am developing IOS App. I Create TextField and Button Dynamically and Set tag value.but problem is that when click button to get textfield first index value that show null. only last index value of textfield i am get not for other What is the problem. Thanks in Advance.
Code..
- (void)addfields{
_field = [[UITextField alloc]initWithFrame:CGRectMake(5.0f, 5.0f, 195.0f, 30.0f)];
_field.layer.borderColor=[[UIColor colorWithRed:211.0f/255.0f
green:211.0f/255.0f
blue:211.0f/255.0f
alpha:1.0] CGColor];
[_field.layer setBorderWidth: 1.0];
//_field.tag = count;
[_filterPossibleValueView addSubview:_field];
_addField = [[UIButton alloc]initWithFrame:CGRectMake(202.0f, 5.0f, 30.0f, 30.0f)];
_addField.backgroundColor = [UIColor blackColor];
//_addField.tag = count;
[_addField addTarget:self action:#selector(customFieldAdd:) forControlEvents:UIControlEventTouchUpInside];
[_filterPossibleValueView addSubview:_addField];
}
- (IBAction)customFieldAdd:(id)sender{
[_addfieldArray addObject:_field];
[_scroller setScrollEnabled:YES];
_scroller.contentSize=CGSizeMake(240.0f, _field.frame.size.height+x+50);
[_copyfield removeFromSuperview];
[copyAddButton removeFromSuperview];
x = 10;
y = 10;
for( int i = 0; i < [_addfieldArray count]; i++ ) {
_copyfield = [[UITextField alloc]initWithFrame:CGRectMake(5.0, x + _field.frame.size.height, 195.0f, 30.0f)];
_copyfield.layer.borderColor=[[UIColor colorWithRed:211.0f/255.0f
green:211.0f/255.0f
blue:211.0f/255.0f
alpha:1.0] CGColor];
_copyfield.tag = i;
[_copyfield.layer setBorderWidth: 1.0];
[_filterPossibleValueView addSubview:_copyfield];
x = x+_field.frame.size.height+10;
copyAddButton = [[UIButton alloc]initWithFrame:CGRectMake(202.0f, y + _addField.frame.size.height, 30.0f, 30.0f)];
copyAddButton.backgroundColor = [UIColor blueColor];
copyAddButton.tag = i;
[copyAddButton addTarget:self action:#selector(customFieldDelete:) forControlEvents:UIControlEventTouchUpInside];
[_filterPossibleValueView addSubview:copyAddButton];
y = y+_addField.frame.size.height+10;
count++;
}
}
- (IBAction)customFieldDelete:(id)sender{
UIButton *button = (UIButton*)sender;
NSInteger index = button.tag;
[_addfieldArray removeObjectAtIndex:index];
// UITextField *text = (UITextField *)[_copyfield viewWithTag:index];
// NSLog(#"%ld",(long)text.tag);
UITextField *txtField = [_filterPossibleValueView viewWithTag:index];
NSLog(#"%#",txtField.text);
// [_copyfield removeFromSuperview];
// [copyAddButton removeFromSuperview];
}
I have created an sample app for dynamic fields. And getting the textfield's value on Button click. This example code will solve out your problem.
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
NSMutableArray *formArr;
NSMutableArray *txtfldArr;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
formArr = [[NSMutableArray alloc] init];
txtfldArr = [[NSMutableArray alloc] init];
UITextField *txtfld = [[UITextField alloc] init];
NSMutableDictionary *dict1 = [[NSMutableDictionary alloc] init];
[dict1 setObject:#"string" forKey:#"labelName"];
[dict1 setObject:#"name" forKey:#"labelFor"];
[dict1 setObject:#"1" forKey:#"tag"];
[dict1 setObject:txtfld forKey:#"txtFld"];
[formArr addObject:dict1];
NSMutableDictionary *dict2 = [[NSMutableDictionary alloc] init];
[dict2 setObject:#"string" forKey:#"labelName"];
[dict2 setObject:#"email" forKey:#"labelFor"];
[dict2 setObject:#"2" forKey:#"tag"];
[dict2 setObject:txtfld forKey:#"txtFld"];
[formArr addObject:dict2];
NSMutableDictionary *dict3 = [[NSMutableDictionary alloc] init];
[dict3 setObject:#"string" forKey:#"labelName"];
[dict3 setObject:#"phone" forKey:#"labelFor"];
[dict3 setObject:#"3" forKey:#"tag"];
[dict3 setObject:txtfld forKey:#"txtFld"];
[formArr addObject:dict3];
NSMutableDictionary *dict4 = [[NSMutableDictionary alloc] init];
[dict4 setObject:#"string" forKey:#"labelName"];
[dict4 setObject:#"address" forKey:#"labelFor"];
[dict4 setObject:#"4" forKey:#"tag"];
[dict4 setObject:txtfld forKey:#"txtFld"];
[formArr addObject:dict4];
int y = 70;
for (int i = 0; i < [formArr count]; i++) {
NSString *txtfldName = [NSString stringWithFormat:#"%#",[[formArr objectAtIndex:i] objectForKey:#"labelFor"]];
UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(30, y+4, 80, 25)];
lbl.text = txtfldName;
lbl.textColor = [UIColor darkGrayColor];
[self.view addSubview:lbl];
UITextField *lbl_txtfld = [[UITextField alloc] initWithFrame:CGRectMake(120, y, 150, 30)];
lbl_txtfld.text = #"";
lbl_txtfld.delegate = self;
lbl_txtfld.textColor = [UIColor whiteColor];
lbl_txtfld.backgroundColor = [UIColor blackColor];
[self.view addSubview:lbl_txtfld];
[[formArr objectAtIndex:i] setObject:lbl_txtfld forKey:#"txtFld"];
y += 40;
}
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)buttonClicked:(id)sender {
for (int i = 0; i < [formArr count]; i++) {
NSString *labelName = [NSString stringWithFormat:#"%#",[[formArr
objectAtIndex:i] objectForKey:#"labelFor"]];
UITextField *txtfld = [[formArr objectAtIndex:i]
objectForKey:#"txtFld"];
NSLog(#"txtfld value for %# = %#",labelName,txtfld.text);
}
}
I have four images on a Viewcontroller A .On the click of those images Viewcontroller B having UIScrollView presents that has image view and it shows all those four imgaes....Image1 ,image 2,image 3,image 4.
I want that when image 2 is clicked then image 2 appeas as the first image on Viewcontroller B ,then image 3,then image 4...Also,when user moves left then it shows previous images including image1 too.
I have searched a lot but couldn't find solution to this problem Kindly.help
The code I have used are as follows:
- (void)viewDidLoad {
[super viewDidLoad];
width = [UIScreen mainScreen].bounds.size.width;
height = [UIScreen mainScreen].bounds.size.height;
_scroller = [[UIScrollView alloc]initWithFrame:
CGRectMake(0,64,width,height)];
_scroller.contentSize=CGSizeMake(pageCount*_scroller.bounds.size.width,_scroller.bounds.size.height);
_scroller.pagingEnabled=YES;
_scroller.showsHorizontalScrollIndicator=YES;
CGRect ViewSize=_scroller.bounds;
NSArray *imgArray = [self.tripDetails valueForKey:#"Flightimageurl"];
for(int i=0;i<[imgArray count];i++)
{
UIImageView *imgView1=[[UIImageView alloc]initWithFrame:ViewSize];
NSString *ImageURL = [imgArray objectAtIndex:i];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];
imgView1.image=[UIImage imageWithData:imageData];
[_scroller addSubview:imgView1];
[self.view addSubview:_scroller];
ViewSize =CGRectOffset(ViewSize,_scroller.bounds.size.width,0);
}
}
Use This Code It will be helpful to you
-(void)singleTapping:(UIGestureRecognizer *)recognizer {
int imageTag = (int) recognizer.view.tag;
NSDictionary *dictCurrentWish = [arrLatestScrollData objectAtIndex:pageNumberSaved];
scrollimagePostView = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0, kSCREEN_WIDTH, kSCREEN_HEIGHT)];
scrollimagePostView.pagingEnabled=YES;
scrollimagePostView.delegate=self;
UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[scrollimagePostView addGestureRecognizer:gr];
NSMutableArray *arrTotalImages = [[NSMutableArray alloc]initWithCapacity:0];
[arrTotalImages addObject:[dictCurrentWish objectForKey:#"pic1"]];
[arrTotalImages addObject:[dictCurrentWish objectForKey:#"pic2"]];
[arrTotalImages addObject:[dictCurrentWish objectForKey:#"pic3"]];
[arrTotalImages addObject:[dictCurrentWish objectForKey:#"pic4"]];
int x=0;
CGRect innerScrollFrame = scrollimagePostView.bounds;
for (int i=0; i<arrTotalImages.count; i++) {
imgViewPost=[[UIImageView alloc]initWithFrame:CGRectMake(x, 60, kSCREEN_WIDTH,kSCREEN_HEIGHT-90)];
NSString *strImage =[NSString stringWithFormat:#"%#", [arrTotalImages objectAtIndex:i]];
NSString *strURL=[strImage stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSURL* urlAddress1 = [[NSURL alloc] initWithString:strURL];
[imgViewPost sd_setImageWithURL:urlAddress1 placeholderImage:wishPlaceHolderImage];
imgViewPost.contentMode = UIViewContentModeScaleAspectFit;
imgViewPost.tag = VIEW_FOR_ZOOM_TAG;
UIScrollView *pageScrollView = [[UIScrollView alloc]
initWithFrame:innerScrollFrame];
pageScrollView.minimumZoomScale = 1.0f;
pageScrollView.maximumZoomScale = 6.0f;
pageScrollView.zoomScale = 1.0f;
pageScrollView.contentSize = imgViewPost.bounds.size;
pageScrollView.delegate = self;
pageScrollView.showsHorizontalScrollIndicator = NO;
pageScrollView.showsVerticalScrollIndicator = NO;
[pageScrollView addSubview:imgViewPost];
[scrollimagePostView addSubview:imgViewPost];
x=x+kSCREEN_WIDTH;
if (i < 2) {
innerScrollFrame.origin.x += innerScrollFrame.size.width;
}
}
scrollimagePostView.contentSize = CGSizeMake(x, scrollimagePostView.frame.size.height );
scrollimagePostView.backgroundColor = [UIColor blackColor];
[self.view addSubview:scrollimagePostView];
[scrollimagePostView setContentOffset:CGPointMake(scrollimagePostView.frame.size.width*(imageTag-1), 0.0f) animated:NO];
btnCloseFullIMageView = [[UIButton alloc]initWithFrame:CGRectMake(kSCREEN_WIDTH-80, 25, 70, 25)];
[btnCloseFullIMageView setTitle:#"Close" forState:UIControlStateNormal];
[btnCloseFullIMageView setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
btnCloseFullIMageView.backgroundColor = [UIColor blackColor];
btnCloseFullIMageView.layer.borderColor = [UIColor whiteColor].CGColor;
btnCloseFullIMageView.layer.borderWidth = 0.5;
btnCloseFullIMageView.layer.cornerRadius = 3.0;
btnCloseFullIMageView.clipsToBounds = TRUE;
[btnCloseFullIMageView addTarget:self action:#selector(closeFullImageView:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btnCloseFullIMageView];
}
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 have created a google map view where I placed some annotations and placing them at the time of loading, but when I change my camera view continuously, memory consumption gets too high about 200MB. FPS rate also lowers down from 30 to 5or6. My app goes nothing but crashing. How can I release that memory ? Here is my code of what I am doing when I move camera angle,
- (void)mapView:(GMSMapView *)mapview didChangeCameraPosition:(GMSCameraPosition *)position
{
[self updateCenterOfScreenMarker:position.target];
}
- (void)updateCenterOfScreenMarker:(CLLocationCoordinate2D)coordinate {
[self updateMarkers:currentLocation];
CLLocation * centerOfGreen = [self getLocationCenterOfGreen];
if (centerOfGreen) {
CLLocation * currentCamera = [[CLLocation alloc] initWithLatitude:coordinate.latitude longitude:coordinate.longitude];
CLLocationDistance distance = [currentCamera distanceFromLocation:centerOfGreen];
distanceFromCameraToGolfer = [currentCamera distanceFromLocation:currentLocation];
[currentCamera release];
distanceFromCameraToCenterOfGreen = distance;
if (isYards) {
distanceFromCameraToCenterOfGreen *= METERS_TO_YARDS;
distanceFromCameraToGolfer *= METERS_TO_YARDS;
}
if (centerMarker) {
centerMarker.map = nil; // You can remove a marker from the map by setting your GMSMarker's map property to nil.
[centerMarker release];
centerMarker = nil;
headingLabel.text=#"";
headingLabel=nil;
headingLabel.text=nil;
headingLabel2.text=#"";
headingLabel2=nil;
headingLabel2.text=nil;
headingLabel3.text=#"";
headingLabel3=nil;
headingLabel3.text=nil;
headingLabel4.text=#"";
headingLabel4=nil;
headingLabel4.text=nil;
centerMarker.icon =nil;
}
if (mapView) {
// centerMarker = [GMSMarker markerWithPosition:coordinate];
headingLabel.text=#"";
headingLabel2.text=#"";
headingLabel3.text=#"";
headingLabel4.text=#"";
if(distanceFromCameraToGolfer >= 1000)
{
headingLabel = [[UILabel alloc] initWithFrame:CGRectMake(40, 180, 120, 30)];
headingLabel2 = [[UILabel alloc] initWithFrame:CGRectMake(160, 180, 40, 30)];
headingLabel3 = [[UILabel alloc] initWithFrame:CGRectMake(200, 180, 20, 30)];
headingLabel4 = [[UILabel alloc] initWithFrame:CGRectMake(225, 180, 70, 30)];
}
else
{
headingLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 180, 100, 30)];
headingLabel2 = [[UILabel alloc] initWithFrame:CGRectMake(125, 180, 40, 30)];
headingLabel3 = [[UILabel alloc] initWithFrame:CGRectMake(170, 180, 20, 30)];
headingLabel4 = [[UILabel alloc] initWithFrame:CGRectMake(195, 180, 70, 30)];
}
headingLabel.font=[UIFont fontWithName:#"Roboto-Bold" size:30];
headingLabel2.font=[UIFont fontWithName:#"Roboto-Regular" size:30];
headingLabel3.font=[UIFont fontWithName:#"Roboto-Light" size:30];
headingLabel4.font=[UIFont fontWithName:#"Roboto-Bold" size:30];
headingLabel.textColor=[UIColor whiteColor];
headingLabel2.textColor=[UIColor whiteColor];
headingLabel3.textColor=[UIColor yellowColor];
headingLabel4.textColor=[UIColor whiteColor];
headingLabel.textAlignment=NSTextAlignmentRight;
headingLabel2.textAlignment=NSTextAlignmentCenter;
headingLabel3.textAlignment=NSTextAlignmentCenter;
headingLabel4.textAlignment=NSTextAlignmentLeft;
headingLabel.text=nil;
headingLabel2.text=nil;
headingLabel3.text=nil;
headingLabel4.text=nil;
// centerMarker.title = nil;
// centerMarker.snippet = nil;
// centerMarker.groundAnchor = CGPointMake(0.5, 0.5);
str=#"";
str = [NSString stringWithFormat:#"%d",distanceFromCameraToGolfer];
str2=#"";
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
NSString * units = [defaults objectForKey:PREFERENCE_KEY_UNITS];
if ([units isEqualToString:#"yards"]) {
str2 = [NSString stringWithFormat:#"Yd"];
}
else
{
str2 = [NSString stringWithFormat:#" m"];
}
str3=#"";
str3 = [NSString stringWithFormat:#"/"];
str4=#"";
str4 = [NSString stringWithFormat:#"%d", distanceFromCameraToCenterOfGreen];
if([str4 intValue]>=0 && [str4 intValue]<=14)
{
headingLabel.hidden=YES;
headingLabel2.hidden=YES;
headingLabel3.hidden=YES;
headingLabel4.hidden=YES;
}
headingLabel.text=str;
headingLabel2.text=str2;
headingLabel3.text=str3;
headingLabel4.text=str4;
[mapView addSubview:headingLabel];
[mapView addSubview:headingLabel2];
[mapView addSubview:headingLabel3];
[mapView addSubview:headingLabel4];
// centerMarker.icon = [self addText:[UIImage imageNamed:#"grid.png"] text:#"" red:255 green:255 blue:255];
// centerMarker.map = mapView;
// centerMarker.tappable=NO;
[centerMarker retain];
[headingLabel release];
[headingLabel2 release];
[headingLabel3 release];
[headingLabel4 release];
} // mapView
}
}
Here in above code heading labels are the labels that show distance from current location to camera position.
Following is the image of memory consumption and FPS.
You can try,
change in this delegate method:
- (void)mapView:(GMSMapView *)mapView idleAtCameraPosition:(GMSCameraPosition *)position{
[self updateCenterOfScreenMarker:position.target];
}
I am using UIScrollView in my app that 25 view first time.
user scroll on bottom next 25 view add in scrollview.
I am still entirely not sure this is a memory problem.But i didn't found the code cause of the Memory Problem.
Even I have checked memory leak issue through the instrument tool there is no memory leak.
My code:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
float scrollViewHeight = _scrl_ipad.frame.size.height;
float scrollContentSizeHeight = _scrl_ipad.contentSize.height;
float scrollOffset = _scrl_ipad.contentOffset.y;
if (scrollOffset == 0)
{
}
else if (scrollOffset + scrollViewHeight == scrollContentSizeHeight)
{
if (scrl_bottom_reload_view)
{
scrl_bottom_reload_view=nil;
[scrl_bottom_reload_view release];
}
scrl_bottom_reload_view = [[UIView alloc]initWithFrame:CGRectMake(10, scrollContentSizeHeight-100, _scrl_ipad.frame.size.width-20, 60.0)];
scrl_bottom_reload_view.tag = -50;
UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake((_scrl_ipad.frame.size.width/2)-100, 10, 200, 40)];
lbl.font = [UIFont fontWithName:#"ArialMT" size:22];
lbl.textColor = [UIColor darkGrayColor];
lbl.backgroundColor = [UIColor clearColor];
lbl.text = #"Loading deals...";
[scrl_bottom_reload_view addSubview:lbl];
[lbl release];
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityIndicator.alpha = 1.0;
activityIndicator.color = [UIColor lightGrayColor];
activityIndicator.frame = CGRectMake((_scrl_ipad.frame.size.width/2)-150, 12, 37, 37);
activityIndicator.hidesWhenStopped = NO;
[scrl_bottom_reload_view addSubview:activityIndicator];
[activityIndicator startAnimating];
scrl_bottom_reload_view.hidden = FALSE;
scrl_bottom_reload_view.backgroundColor = [UIColor clearColor];
[self.scrl_ipad addSubview:scrl_bottom_reload_view];
[self performSelector:#selector(LoadScrl) withObject:nil afterDelay:0.3];
}
}
-(void)LoadScrl
{
//called api and fill arrayalldeals arry
[self func_scrl_ipad];
}
-(void)func_scrl_ipad
{
NSArray *viewsToRemove = [_scrl_ipad subviews];
for (UIView *view in viewsToRemove)
{
[view removeFromSuperview];
view = nil;
}
int temp;
if([arrayalldeals count] % 2 == 0)
{
temp = ([arrayalldeals count] / 2);
}
else
{
temp = ([arrayalldeals count] / 2) + 1;
}
_scrl_ipad.contentSize = CGSizeMake(768,(258*temp)+150);
_scrl_ipad.showsVerticalScrollIndicator=NO;
int x = 35;
int y = 35;
for (int i = 1 ; i <= [arrayalldeals count]; i++)
{
UIView *bgview = [[UIView alloc]initWithFrame:CGRectMake(x, y, 328, 243)];
bgview.backgroundColor = [UIColor whiteColor];
//bgview.layer.borderWidth = 0;
//bgview.layer.cornerRadius = 0;
bgview.tag = i;
//bgview.layer.masksToBounds = YES;
//bgview.layer.borderColor =[[UIColor clearColor] CGColor];
//bgview.layer.shadowColor = [[UIColor whiteColor] CGColor];
//bgview.layer.shadowOffset = CGSizeMake(0.0, 0.0);
//bgview.layer.shadowOpacity = 0.0;
AsyncImageView *imageView = [[AsyncImageView alloc] initWithFrame:CGRectMake(0, 0, 328, 223)];
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.clipsToBounds = YES;
imageView.layer.cornerRadius = 0;
imageView.imageURL =[NSURL URLWithString:[NSString stringWithFormat:#"%#uploads/%#-5.jpg",app.Main_url,[[arrayalldeals objectAtIndex:i-1] objectForKey:#"deal_id"]]];
//cell.autoresizesSubviews=YES;
[bgview addSubview:imageView];
[imageView release];
UIView *shadoeview = [[UIView alloc]initWithFrame:CGRectMake(0,115, 328, 112)];
CAGradientLayer *bgLayer = [BackgroundLayer greyGradient];
bgLayer.frame = shadoeview.bounds;
[shadoeview.layer insertSublayer:bgLayer atIndex:0];
shadoeview.alpha = 0.9;
[bgview addSubview:shadoeview];
[shadoeview release];
UIImageView *img_discount = [[UIImageView alloc]initWithFrame:CGRectMake(0,0, 57, 57)];
img_discount.image = [UIImage imageNamed:#"discount_tag.png"];
[bgview addSubview:img_discount];
[img_discount release];
UILabel *lbl_disc_text=[[UILabel alloc]init];
lbl_disc_text.frame=CGRectMake(-2,-10,100,20);
lbl_disc_text.backgroundColor=[UIColor clearColor];
lbl_disc_text.font = [UIFont fontWithName:#"ArialMT" size:14];
lbl_disc_text.textColor = [UIColor whiteColor];
int disc = 0;
if([NSNull null] != [[arrayalldeals objectAtIndex:i-1] objectForKey:#"value"])
{
int main_price = [[[arrayalldeals objectAtIndex:i-1] objectForKey:#"value"] intValue];
int disc_price = [[[arrayalldeals objectAtIndex:i-1] objectForKey:#"price"] intValue];
int multiply = disc_price *100 /main_price;
disc = 100 - multiply;
}
lbl_disc_text.text = [NSString stringWithFormat:#"- %d%%",disc];
[bgview addSubview:lbl_disc_text];
float degrees = -40; //the value in degrees
lbl_disc_text.transform = CGAffineTransformMakeRotation(degrees * M_PI/180);
[lbl_disc_text release];
UILabel *lbl_desc=[[UILabel alloc]init];
lbl_desc.frame=CGRectMake(8,162, 240, 50);
lbl_desc.backgroundColor=[UIColor clearColor];
lbl_desc.font = [UIFont fontWithName:#"Arial Rounded MT Bold" size:16];
lbl_desc.textColor = [UIColor whiteColor];
lbl_desc.numberOfLines = 2 ;
if([NSNull null] != [[arrayalldeals objectAtIndex:i-1] objectForKey:#"name"])
{
lbl_desc.text=[NSString stringWithFormat:#"%#",[[arrayalldeals objectAtIndex:i-1] objectForKey:#"name"]];
}
else
{
lbl_desc.text=#"";
}
[bgview addSubview:lbl_desc];
[lbl_desc release];
UILabel *lbl_unprice=[[UILabel alloc]init];
lbl_unprice.frame=CGRectMake(255,165,60,20);
lbl_unprice.backgroundColor=[UIColor clearColor];
lbl_unprice.textAlignment = NSTextAlignmentRight;
lbl_unprice.textColor = [UIColor whiteColor];
lbl_unprice.font = [UIFont fontWithName:#"ArialMT" size:14];
if([NSNull null] != [[arrayalldeals objectAtIndex:i-1] objectForKey:#"value"])
{
int unprice = [[[arrayalldeals objectAtIndex:i-1] objectForKey:#"value"] intValue];
lbl_unprice.text = [NSString stringWithFormat:#"$%d",unprice];
}
else
{
lbl_unprice.text=[NSString stringWithFormat:#"$0"];
}
[bgview addSubview:lbl_unprice];
[lbl_unprice release];
NSString *str_price_line;
if([NSNull null] != [[arrayalldeals objectAtIndex:i-1] objectForKey:#"value"])
{
int unprice = [[[arrayalldeals objectAtIndex:i-1] objectForKey:#"value"] intValue];
str_price_line = [NSString stringWithFormat:#"$%d",unprice];
}
else
{
str_price_line=[NSString stringWithFormat:#"$0"];
}
UIFont *font = [UIFont fontWithName:#"ArialMT" size:14];
CGSize size = [(str_price_line ? str_price_line : #"") sizeWithFont:font constrainedToSize:CGSizeMake(281, 9999) lineBreakMode:NSLineBreakByWordWrapping];
int temp = 60 - size.width;
UILabel *lbl_line=[[UILabel alloc]init];
lbl_line.frame=CGRectMake(253+temp,174,size.width+4,2);
lbl_line.backgroundColor=[UIColor colorWithRed:252.0/255.0 green:36.0/255.0 blue:148.0/255.0 alpha:1.0];
float degre = -20; //the value in degrees
lbl_line.transform = CGAffineTransformMakeRotation(degre * M_PI/250);
[bgview addSubview:lbl_line];
[lbl_line release];
UILabel *lbl_price=[[UILabel alloc]init];
lbl_price.frame=CGRectMake(215,180, 100, 35);
lbl_price.textAlignment = NSTextAlignmentRight;
lbl_price.backgroundColor=[UIColor clearColor];
lbl_price.font = [UIFont fontWithName:#"ArialMT" size:24];
lbl_price.textColor = [UIColor colorWithRed:93.0/255.0 green:202.0/255.0 blue:242.0/255.0 alpha:1.0];
if([NSNull null] != [[arrayalldeals objectAtIndex:i-1] objectForKey:#"price"])
{
int price = [[[arrayalldeals objectAtIndex:i-1] objectForKey:#"price"] intValue];
lbl_price.text = [NSString stringWithFormat:#"$%d",price];
}
else
{
lbl_price.text=[NSString stringWithFormat:#"$0"];
}
[bgview addSubview:lbl_price];
[lbl_price release];
UILabel *lbl_bottom_view=[[UILabel alloc]init];
lbl_bottom_view.frame=CGRectMake(0,223, 328,20);
lbl_bottom_view.backgroundColor=[UIColor darkGrayColor];
[bgview addSubview:lbl_bottom_view];
[lbl_bottom_view release];
UILabel *lbl_vertical1=[[UILabel alloc]init];
lbl_vertical1.frame=CGRectMake(100,223,2,20);
lbl_vertical1.backgroundColor=[UIColor grayColor];
[bgview addSubview:lbl_vertical1];
[lbl_vertical1 release];
UILabel *lbl_vertical2=[[UILabel alloc]init];
lbl_vertical2.frame=CGRectMake(222,223,2,20);
lbl_vertical2.backgroundColor=[UIColor grayColor];
[bgview addSubview:lbl_vertical2];
[lbl_vertical2 release];
UILabel *lbl_address=[[UILabel alloc]init];
lbl_address.frame=CGRectMake(4,226, 94, 14);
lbl_address.textAlignment = NSTextAlignmentCenter;
lbl_address.backgroundColor=[UIColor clearColor];
lbl_address.font = [UIFont fontWithName:#"ArialMT" size:12];
lbl_address.textColor = [UIColor whiteColor];
if ((NSNull *)app.city_dict == NULL)
{
lbl_address.text= #"Vancouver";
}
else
{
lbl_address.text=[NSString stringWithFormat:#"%#",[app.city_dict objectForKey:#"title"]];
}
[bgview addSubview:lbl_address];
[lbl_address release];
//LeftTime
NSString *strDatehere = [NSString stringWithFormat:#"%#",[[arrayalldeals objectAtIndex:i-1] objectForKey:#"d_expires"]];
NSDateFormatter *heredateFormatter = [[NSDateFormatter alloc] init];
[heredateFormatter setDateFormat:#"yyyy-MM-dd"]; // set date formate with your dates
NSDate *datehere = [heredateFormatter dateFromString: strDatehere];
NSTimeInterval timeDifference = [datehere timeIntervalSinceDate:[NSDate date]];
[heredateFormatter release];
double hours = timeDifference / 3600;
NSInteger remainder = ((NSInteger)timeDifference)% 3600;
double minutes = remainder / 60;
double seconds = remainder % 60;
NSString *strleft_time = [NSString stringWithFormat:#"%.0fh, %.0fm, %.0fs",hours,minutes,seconds];
UILabel *lbl_time=[[UILabel alloc]init];
lbl_time.frame=CGRectMake(105,226, 110, 14);
lbl_time.textAlignment = NSTextAlignmentCenter;
lbl_time.backgroundColor=[UIColor clearColor];
lbl_time.font = [UIFont fontWithName:#"ArialMT" size:12];
lbl_time.textColor = [UIColor whiteColor];
lbl_time.text=strleft_time;
[bgview addSubview:lbl_time];
[lbl_time release];
UILabel *lbl_bought=[[UILabel alloc]init];
lbl_bought.frame=CGRectMake(222,226, 98, 14);
lbl_bought.textAlignment = NSTextAlignmentCenter;
lbl_bought.backgroundColor=[UIColor clearColor];
lbl_bought.font = [UIFont fontWithName:#"ArialMT" size:12];
lbl_bought.textColor = [UIColor whiteColor];
lbl_bought.text= [NSString stringWithFormat:#"%# Bought",[[arrayalldeals objectAtIndex:i-1] objectForKey:#"buys"]];
[bgview addSubview:lbl_bought];
[lbl_bought release];
UIButton *btn_scrl=[UIButton buttonWithType:UIButtonTypeCustom];
[btn_scrl setFrame:CGRectMake(0,0, 328, 243)];
btn_scrl.tag=i-1;
[btn_scrl addTarget:self action:#selector(btn_scrl_tag:) forControlEvents:UIControlEventTouchUpInside];
[bgview addSubview:btn_scrl];
UIButton *btn_fav=[UIButton buttonWithType:UIButtonTypeCustom];
[btn_fav setFrame:CGRectMake(285,5, 35, 35)];
if([[[arrayalldeals objectAtIndex:i-1] objectForKey:#"user_faves"] isEqualToString:#"1"])
{
[btn_fav setBackgroundImage:[UIImage imageNamed:#"all_deals_fave_pink_icon.png"] forState:UIControlStateNormal];
}
else
{
[btn_fav setBackgroundImage:[UIImage imageNamed:#"all_deals_fave_icon.png"] forState:UIControlStateNormal];
}
[btn_fav.titleLabel setFont:[UIFont boldSystemFontOfSize:12]];
if([[[arrayalldeals objectAtIndex:i-1] objectForKey:#"faves"] isEqualToString:#"0"])
{
[btn_fav setTitle:#"" forState:UIControlStateNormal];
}
else
{
[btn_fav setTitle:[NSString stringWithFormat:#"%#",[[arrayalldeals objectAtIndex:i-1] objectForKey:#"faves"]] forState:UIControlStateNormal];
}
btn_fav.tag=i-1;
[btn_fav addTarget:self action:#selector(btn_favorite:) forControlEvents:UIControlEventTouchUpInside];
[bgview addSubview:btn_fav];
[_scrl_ipad addSubview:bgview];
[bgview release];
if(i % 2 == 0)
{
y = y + 258;
x = 35;
}
else
{
x = 399;
}
}
}
}
////
now api called more then 10 times i got Terminated due to Memory Pressure Error and App crase
Didn't understand, what are you trying to do? But found many bugs in your code. List out some of them.
1) In this line, you already set as nil and try to release nil object. This won't release any object, this is main reason for memory leak.
if (scrl_bottom_reload_view)
{
scrl_bottom_reload_view=nil;
[scrl_bottom_reload_view release];
}
2) Try to assign nil to local variable which does nothing.
for (UIView *view in viewsToRemove)
{
[view removeFromSuperview];
view = nil;
}
3) Where did you release this object.
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc].....
Suggestion : Above code is more complex, try with Tableview. Use xib to like this job. Otherwise more complex to design as well consume more time to develop.