I am building an app using storyboard. I have a view controller where the user has a set of tools (UILabels, images...), and can add these items by clicking on a specific button. When I exit the view controller or closes the app though all the data is lost. so I tried setting up a save button in this way:
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *cameraButton = [[UIBarButtonItem alloc]
initWithTitle:#"Camera"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(useCamera:)];
UIBarButtonItem *cameraRollButton = [[UIBarButtonItem alloc]
initWithTitle:#"Camera Roll"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(useCameraRoll:)];
NSArray *items = [NSArray arrayWithObjects: cameraButton,
cameraRollButton, nil];
[toolbar setItems:items animated:NO];
mouseMoved = 0;
array = [[NSMutableArray alloc]init];
array2 = [[NSMutableArray alloc]init];
array3 = [[NSMutableArray alloc]init];
NSFileManager *filemgr; NSString *docsDir; NSArray *dirPaths;
filemgr = [NSFileManager defaultManager];
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
// Build the path to the data file
dataFilePath = [[NSString alloc] initWithString: [docsDir
stringByAppendingPathComponent: #"data.archive"]];
// Check if the file already exists
if ([filemgr fileExistsAtPath: dataFilePath]) {
dataArray = [NSKeyedUnarchiver unarchiveObjectWithFile: dataFilePath];
array = [dataArray objectAtIndex:0]; array2 = [dataArray objectAtIndex:1]; array3 = [dataArray objectAtIndex:2];
}}
-(void)saveData{
NSMutableArray *contactArray;
contactArray = [[NSMutableArray alloc] init]; [contactArray addObjectsFromArray:array]; [contactArray addObjectsFromArray:array2]; [contactArray addObjectsFromArray:array3]; [NSKeyedArchiver archiveRootObject:
contactArray toFile:dataFilePath];
[self.view addSubview: image1];
[self.view addSubview: text1];
[self.view addSubview: label1];
}
when I press the buttons the you can see that the codes are triggers (NSLog), but nothing happens. in the above example when I click save, the UILabel the user has created (alloc), should be saved, and when the app is open again, the button unarchive should place the label exactly how it is, and in the same position. I have to do tho even for the UIImageViews, and UITextFields.
Since I added all the user created labels... in an array, I want to save the whole objects in the array. The above code does not work though. I can't understand why.this is how I created the array and the object (in .h I added NSMutableArray *array;)
CGRect labelFrame = CGRectMake( 400, 100, 100, 30);
label1 = [[UILabel alloc] initWithFrame: labelFrame];
[label1 setText: #"Untitled"];
[label1 setTextColor: [UIColor orangeColor]];
[self.view addSubview:label1];
label1.backgroundColor = [UIColor clearColor];
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scalePiece:)];
[label1 addGestureRecognizer:pinchGesture];
if (array == nil) array = [[NSMutableArray alloc]init];
[array addObject:label1];
thanks in advance for the help!!
Try logging your loaded objects and you should see that they are actually loaded. You don't see them of course since you don't add them to the view hierarchy. Try adding those lines after you get your objects from the dictionary:
[self.view addSubview: label1];
[self.view addSubview: text1];
[self.view addSubview: image1];
This might work, but it is not a good idea though. You really should read some introductory material to object-oriented programming and the Model/View/Controller (MVC) design pattern.
Related
So far I have this:
I am trying to parse date with hpple from a webpage and then display it in labels. I don't know how to go about this. I guess I have to make the Secret variable in the void GoToSecretsList somehow equal the values the other void is getting... does anyone have any suggestions?
- (void)GoToSecretsList
{
UIViewController *vc;
vc = [self.storyboard instantiateViewControllerWithIdentifier:#"SecretsListID"];
[self.navigationController pushViewController:vc animated:YES];
UILabel *myLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 120, 500, 40)];
[myLabel setBackgroundColor:[UIColor clearColor]];
NSString *Secret;
Secret = #"Get value from website";
[myLabel setText:[NSString stringWithFormat:#"#1: %#", Secret]];
[[vc view] addSubview:myLabel];
}
-(void)LoadSecrets {
// 1
NSURL *SecretsUrl = [NSURL URLWithString:#"http:/removed.com/xlxlx"];
NSData *SecretsHtmlData = [NSData dataWithContentsOfURL:SecretsUrl];
// 2
TFHpple *secretsParser = [TFHpple hppleWithHTMLData:SecretsHtmlData];
// 3
NSString *secretsXpathQueryString = #"/secret";
NSArray *secretsNodes = [secretsParser searchWithXPathQuery:secretsXpathQueryString];
// 4
NSMutableArray *newSecrets = [[NSMutableArray alloc] initWithCapacity:0];
for (TFHppleElement *element in secretsNodes) {
// 5
VOI *secret = [[VOI alloc] init];
[newSecrets addObject:secret];
// 6
secret.title = [[element firstChild] content];
// 7
secret.url = [element objectForKey:#"href"];
}
}
Edit: Now I just have this:
- (void)GoToSecretsList
{
UIViewController *vc;
vc = [self.storyboard instantiateViewControllerWithIdentifier:#"SecretsListID"];
[self.navigationController pushViewController:vc animated:YES];
UILabel *myLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 120, 500, 40)];
[myLabel setBackgroundColor:[UIColor clearColor]];
NSURL *SecretsUrl = [NSURL URLWithString:#"http://removed.com/dsdsds"];
NSData *SecretsHtmlData = [NSData dataWithContentsOfURL:SecretsUrl];
TFHpple *secretsParser = [TFHpple hppleWithHTMLData:SecretsHtmlData];
NSString *secretsXpathQueryString = #"/secret";
NSArray *secretsNodes = [secretsParser searchWithXPathQuery:secretsXpathQueryString];
[myLabel setText:[NSString stringWithFormat:#"#1: %#", secretsNodes]];
[[vc view] addSubview:myLabel];
}
But what variable has the information..? or what I am doing wrong? Because secretNodes isn't it.
Can you post some real html to help know what text you're looking for?
e.g. the following will get all the <h2></h2> nodes:
NSString *secretsXpathQueryString = #"//h2";//note double slashes for tag name
whereas this will get those with a specific class:
NSString *secretsXpathQueryString = #"//h2[#class='secret']";//note single quotes
Once you have the correct query, take a look at TFHppleElement.h to see which properties you might investigate, for example:
element.firstChild.content
I have a UIView that are menuiitems and these menu items are dynamically created where i stamp each uiview tag by increment of 1, but when i want to retrieve the uiview tag values when the user clicks on the menu item i get a different tag number.
I want to retrieve the tag which has the id stored so that i can post that id to a php script.
How do i retrieve the tags form when i set them?
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer {
UIView *tempView = recognizer.view;
NSNumber *tag = [NSNumber numberWithInt:tempView.tag];
int idCat = [tag intValue];
NSLog(#"TAG %d", idCat);
NSURLRequest *request =
[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:
#"http://localhost:8888/MAMP/WHFC/SubCategories.php?categoryid=%d", idCat]]];
int i = 0;
NSError *e;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&e];
NSArray *arrCategoryList =
[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&e];
UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor whiteColor];
UIView *uiView = [[UIView alloc] init];
[uiView setFrame:CGRectMake(0, 480, 320, 480)];
[uiView setBackgroundColor:[UIColor grayColor]];
viewController.view = uiView;
UITableView *uiTableView = [[UITableView alloc] init];
[uiTableView setFrame:CGRectMake(0, 0, 320, 480)];
[uiView addSubview:uiTableView];
[self presentViewController:viewController animated:YES completion:nil];
}
This is the code that creates the menu items in another view:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString: #"http://localhost:8888/MAMP/WHFC/categories.php"]];
int i = 0;
NSError *e;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&e];
NSArray *arrCategoryList = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&e];
for(NSDictionary *dictCategory in arrCategoryList)
{
NSString *strCategoryId = [dictCategory objectForKey:#"CategoryId"];
NSString *strCategoryName = [dictCategory objectForKey:#"Name"];
NSLog(#"%# : %#",strCategoryId,strCategoryName);
UIView *linkMenu = [[UIView alloc] init];
[linkMenu setFrame:CGRectMake(10, i+1, 300, 35)];
linkMenu.tag = [NSString stringWithFormat:#"%d", strCategoryId];
linkMenu.layer.zPosition = 1;
[viewSlide3 addSubview:linkMenu];
[linkMenu setBackgroundColor:[UIColor blueColor]];
linkMenu.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.9];
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSingleTap:)];
[linkMenu addGestureRecognizer:singleFingerTap];
UILabel *labelMenu = [[UILabel alloc] init];
[labelMenu setFrame:CGRectMake(20, 0, 300, 35)];
[labelMenu setFont:[UIFont systemFontOfSize:16]];
[labelMenu setTextColor:[UIColor whiteColor]];
[linkMenu addSubview:labelMenu];
[labelMenu setText:strCategoryName];
i = i + 35 + 1;
}
If you have a UIView lets say A inside which are placed all the other menu items which are also UIViews lets say B, C, and D then most probably the recognizer.view is returning you A no matter which of the B, C, or D are pressed.
Write this in your handleSingleTap function:
CGPoint touchPoint=[gesture locationInView:scrollView];
for(UIView * subView in myView ) //here myView should be the superView A where you have added all the menu item view B, C, and D
{
if(CGRectContainsPoint(subView.bounds, touchPoint))
{
NSNumber *tag = [NSNumber numberWithInt:subView.tag];
}
}
That tag variable will have your final tag that you need.
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
Hello and Thanks for the help.
Is it possible to populate 10 mapview locations from a .plist file using a for loop ? If so how ?
my current code for my mapview is all hard coded. I would like to improve upon this by pulling - Longitude, Latitude, Title, SubTitle - from a for loop if possible. Thank You.
////
.....
MKCoordinateRegion region3 = {{0.0,0.0}, {0.0,0.0}};
region3.center.latitude = 33.45869;
region3.center.longitude = -84.66931;
region3.span.longitudeDelta = 0.01f;
region3.span.latitudeDelta=0.01f;
// [mapview setRegion:region4 animated:YES];
BandsMap *ann3 = [[BandsMap alloc]init];
ann3.title = #"Indigo Bar & Lounge";
ann3.subtitle = #"Let the good times roll";
ann3.coordinate = region3.center;//
////
annoArray = [[NSArray alloc] initWithObjects:ann1,ann2,ann3.....,nil];
[mapView addAnnotations:annoArray];.......
Something like this I suppose but not quite sure how to finish
for(NSDictionary *key in mapDataPlist)
{
NSString *c = [key objectForKey:#"Title"];
NSString *a = [key objectForKey:#"SubTitle"];
NSString *lat = [key objectForKey:#"Latitude"];
NSString *lon = [key objectForKey:#"Longitude"];
CGFloat strFLat = (CGFloat)[lat floatValue];
CGFloat strFLon = (CGFloat)[lon floatValue];
//////
?????
}
Just iterate over your plist array and use the code you have to create the regions from the extracted data. Then, instead of annoArray being an array you create at the end, make it a mutable array and add each item at the end of each loop iteration.
[mapView setRegion:adjustedRegion animated:YES];
mapView.mapType=MKMapTypeStandard;
UITableView *tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain];
tableView.dataSource = self;
tableView.delegate = self;
tableView.frame = CGRectMake(28, 60, 334, 649);
[self.view addSubview:tableView];
NSString *path = [[NSBundle mainBundle] pathForResource:
#"CityList" ofType:#"plist"];
NSMutableArray *cities = [[NSMutableArray alloc] initWithContentsOfFile:path];
NSMutableArray *localCities= [[NSMutableArray alloc]init];
for (int i=0;i<[cities count];i++)
{
NSLog(#"%#",[[cities objectAtIndex:i]objectForKey:#"cityNameKey"]);
[localCities addObject:[[cities objectAtIndex:i]objectForKey:#"cityNameKey"]];
}
locationArray= localCities;
Annotation *annotation=[[Annotation alloc]init];
annotation.coordinate = CLLocationCoordinate2DMake(29.7631,-95.3631);
annotation.color = [UIColor redColor];
annotation.title=[NSString stringWithFormat:#"Houston"];
[mapView addAnnotation:annotation];
in my iOS app's viewDidLoad method, i have the following line of code:
loadDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:#"1.0", "version number", nil];
and it causes an EXC_BAD_ACCESS error. i don't know why. nothing else in the viewDidLoad method uses the object except the other side of the if/else statement this line is in, so there's no way it could have been released already. i'm just not sure what the problem is. if you want to see my whole viewDidLoad method, here it is:
- (void)viewDidLoad
{
[super viewDidLoad];
tapsBackground = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissKeyboard)];
tapsBackground.delegate = self;
[self.view addGestureRecognizer:tapsBackground];
saveChangesButton.hidden = YES;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePath = [documentsDirectory stringByAppendingPathComponent:#"presets.plist"];
if([[NSFileManager defaultManager] fileExistsAtPath:filePath]){
loadDict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
}
else{
loadDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:#"1.0", "version number", nil];
[loadDict writeToFile:filePath atomically:YES];
}
}
The problem is that you are missing # in the second string i.e. "version number".
loadDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:#"1.0", "version number", nil];
It should be,
loadDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:#"1.0", #"version number", nil];
I've faced the same issue once. Try this, it worked for me:
self.loadDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:#"1.0", "version number", nil];
I'm assuming you have already made loadDict a property. You can use Product>Profile>allocations to pin-point the problem in such cases.