I have an NSMutableArray I am trying to populate using a for-loop and making NSStrings for it. These are to be the data source for my UIPickerView. You'll see some commented out lines where I manually made NSArrays and they showed up fine, but my for-loop NSMutableArray doesn't seem to accept the strings I'm making. The NSLogs show that I am making the string (and an equivalent float) alright, but the NSLogs that pull the values from the NSMutableArray show up as null and 0.0
The interface...
// PoolSizePickerViewController.h
#import <UIKit/UIKit.h>
#define kLengthComponent 0
#define kWidthComponent 1
#define kDepthComponent 2
#protocol PoolSizePickerViewControllerDelegate;
#interface PoolSizePickerViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource> {
UIPickerView *poolSizePicker;
float length, width, depth;
NSMutableArray *lengthStrings, *widthStrings, *depthStrings;
NSMutableArray *lengthFloats, *widthFloats, *depthFloats;
NSString *pickerType;
NSString *pickerDescription;
UIButton *selectButton;
UIButton *cancelButton;
UILabel *pickerTitleLabel;
UITextView *pickerDescriptionLabel;
id <PoolSizePickerViewControllerDelegate> delegate;
}
#property (nonatomic, retain) IBOutlet UIPickerView *poolSizePicker;
#property float length, width, depth;
#property (nonatomic, retain) NSMutableArray *lengthStrings, *widthStrings, *depthStrings;
#property (nonatomic, retain) NSMutableArray *lengthFloats, *widthFloats, *depthFloats;
#property (nonatomic, retain) NSString *pickerType;
#property (nonatomic, retain) NSString *pickerDescription;
#property (nonatomic, retain) IBOutlet UIButton *selectButton;
#property (nonatomic, retain) IBOutlet UIButton *cancelButton;
#property (nonatomic, retain) IBOutlet UILabel *pickerTitleLabel;
#property (nonatomic, retain) IBOutlet UITextView *pickerDescriptionLabel;
#property (assign) id <PoolSizePickerViewControllerDelegate> delegate;
- (IBAction)selectedSelectButton;
- (IBAction)selectedCancelButton;
#end
#protocol PoolSizePickerViewControllerDelegate <NSObject>
#optional
- (void)poolSizePickerViewController:(PoolSizePickerViewController *)controller
didSelectLength:(float)length
andWidth:(float)width
andDepth:(float)depth;
- (void)poolSizePickerViewController:(PoolSizePickerViewController *)controller
didSelectCancel:(BOOL)didCancel;
#end
And the implementation...
// PoolSizePickerViewController.m
#import "PoolSizePickerViewController.h"
#implementation PoolSizePickerViewController
#synthesize poolSizePicker;
#synthesize length, width, depth;
#synthesize lengthStrings, widthStrings, depthStrings;
#synthesize lengthFloats, widthFloats, depthFloats;
#synthesize delegate;
#synthesize pickerType, pickerDescription;
#synthesize selectButton, cancelButton;
#synthesize pickerTitleLabel;
#synthesize pickerDescriptionLabel;
- (IBAction)selectedSelectButton {
NSInteger lengthRow = [poolSizePicker selectedRowInComponent:kLengthComponent];
NSInteger widthRow = [poolSizePicker selectedRowInComponent:kWidthComponent];
NSInteger depthRow = [poolSizePicker selectedRowInComponent:kDepthComponent];
length = [[self.lengthFloats objectAtIndex:lengthRow] floatValue];
width = [[self.widthFloats objectAtIndex:widthRow] floatValue];
depth = [[self.depthFloats objectAtIndex:depthRow] floatValue];
if ([self.delegate respondsToSelector:#selector (poolSizePickerViewController:didSelectLength:andWidth:andDepth:)]) {
[self.delegate poolSizePickerViewController:self didSelectLength:length andWidth:width andDepth:depth];
}
}
- (IBAction)selectedCancelButton {
if ([self.delegate respondsToSelector:#selector (poolSizePickerViewController:didSelectCancel:)]) {
[self.delegate poolSizePickerViewController:self didSelectCancel:YES];
}
}
- (void)viewDidLoad {
for (int footIndex = 6; footIndex < 40; footIndex ++) {
for (int inchIndex = 0; inchIndex < 2; inchIndex ++) {
[self.lengthStrings addObject:[NSString stringWithFormat:#" %d' %d\"", footIndex, inchIndex * 6]];
NSLog(#" %d' %d\"", footIndex, inchIndex * 6);
NSLog(#" -%#", [self.lengthStrings objectAtIndex:footIndex - 6]);
[self.lengthFloats addObject:[NSNumber numberWithFloat:(float)footIndex + (float)inchIndex * 0.5f]];
NSLog(#" %1.1f", (float)footIndex + (float)inchIndex * 0.5f);
NSLog(#" -%1.1f", [[self.lengthFloats objectAtIndex:footIndex - 6] floatValue]);
}
}
for (int footIndex = 6; footIndex < 40; footIndex ++) {
for (int inchIndex = 0; inchIndex < 2; inchIndex ++) {
[self.widthStrings addObject:[NSString stringWithFormat:#" %d' %d\"", footIndex, inchIndex * 6]];
[self.widthFloats addObject:[NSNumber numberWithFloat:(float)footIndex + (float)inchIndex * 0.5f]];
}
}
for (int footIndex = 1; footIndex < 16; footIndex ++) {
for (int inchIndex = 0; inchIndex < 2; inchIndex ++) {
[self.depthStrings addObject:[NSString stringWithFormat:#" %d' %d\"", footIndex, inchIndex * 6]];
[self.depthFloats addObject:[NSNumber numberWithFloat:(float)footIndex + (float)inchIndex * 0.5f]];
}
}
// lengthStrings = [NSArray arrayWithObjects:#" 6' 0\"", nil];
// lengthFloats = [NSArray arrayWithObjects:[NSNumber numberWithFloat:1.0], nil];
// widthStrings = [NSArray arrayWithObjects:#" 6' 0\"", nil];
// widthFloats = [NSArray arrayWithObjects:[NSNumber numberWithFloat:2.0], nil];
// depthStrings = [NSArray arrayWithObjects:#" 1' 0\"", nil];
// depthFloats = [NSArray arrayWithObjects:[NSNumber numberWithFloat:3.0], nil];
UIImage *buttonImageNormal = [UIImage imageNamed:#"whiteButton.png"];
UIImage *stretchableButtonImageNormal = [buttonImageNormal stretchableImageWithLeftCapWidth:12 topCapHeight:0];
[selectButton setBackgroundImage:stretchableButtonImageNormal forState:UIControlStateNormal];
[cancelButton setBackgroundImage:stretchableButtonImageNormal forState:UIControlStateNormal];
UIImage *buttonImagePressed = [UIImage imageNamed:#"blueButton.png"];
UIImage *stretchableButtonImagePressed = [buttonImagePressed stretchableImageWithLeftCapWidth:12 topCapHeight:0];
[selectButton setBackgroundImage:stretchableButtonImagePressed forState:UIControlStateHighlighted];
[cancelButton setBackgroundImage:stretchableButtonImagePressed forState:UIControlStateHighlighted];
pickerTitleLabel.text = [NSString stringWithFormat:#"Select a Pool %#", pickerType];
pickerDescriptionLabel.text = self.pickerDescription;
self.poolSizePicker.showsSelectionIndicator = YES;
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)dealloc {
[super dealloc];
}
#pragma mark -
#pragma mark Picker Data Source Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 3;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
switch (component) {
case kLengthComponent:
return [self.lengthStrings count];
break;
case kWidthComponent:
return [self.widthStrings count];
break;
default:
return [self.lengthStrings count];
break;
}
}
#pragma mark Picker Delegate Methods
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component {
switch (component) {
case kLengthComponent:
return [self.lengthStrings objectAtIndex:row];
break;
case kWidthComponent:
return [self.widthStrings objectAtIndex:row];
break;
default:
return [self.depthStrings objectAtIndex:row];
break;
}
}
#end
Are you initializing your arrays somewhere? I don't see an [[NSMutableArray alloc] init] anywhere. Sending a message to a null object is a no-op, so it's likely that those addObjects are being sent to a null and aren't doing anything.
Related
I'm trying to build "slot machine" game using UIPickerView. I populate it using UIImageView. Problem is that, random images in picker view disappear after every spin, and randomly shows again. It happens on device with ios 5.1.1, but on device with ios4.2.1 and simulator it works perfectly. Right now I'm using CircularPickerView but before I used UIPickerView and problem was the same.
Here's screenshot: http://axgrzesiek.w.interii.pl/licznik.PNG
GraViewController.h:
#import <UIKit/UIKit.h>
#import "CircularPickerView.h"
#interface GraViewController : UIViewController
<UIPickerViewDataSource, UIPickerViewDelegate> {
CircularPickerView *picker;
UILabel *winLabel;
NSArray *column1;
NSArray *column2;
NSArray *column3;
}
#property(nonatomic, retain) IBOutlet CircularPickerView *picker;
#property(nonatomic, retain) IBOutlet UILabel *winLabel;
#property(nonatomic, retain) NSArray *column1;
#property(nonatomic, retain) NSArray *column2;
#property(nonatomic, retain) NSArray *column3;
-(IBAction)spin;
#end
GraViewController.m:
- (IBAction)spin {
BOOL win = NO;
int numInRow = 1;
int lastVal = -1;
for (int i = 0; i < 3; i++) {
int newValue = arc4random() % [self.column1 count];
if (newValue == lastVal)
numInRow++;
else
numInRow = 1;
lastVal = newValue;
//if (newValue < [self.column1 count] || newValue >= (2 * [self.column1 count]) ) {
//newValue = newValue % [self.column1 count];
//newValue += [self.column1 count];
[self.picker selectRow:newValue inComponent:i animated:YES];
//}
NSLog(#"kol:%d %d",i, newValue);
//[picker reloadComponent:i];
if (numInRow >= 3)
win = YES;
}
if (win)
winLabel.text = #"WIN!";
else
winLabel.text = #"";
//[picker reloadAllComponents];
//[self performSelector:#selector(moveIntoPosition) withObject:nil afterDelay:0.5f];
- (void)viewDidLoad {
NSString *title=#"Gra";
[self setTitle:title];
UIImage *seven = [UIImage imageNamed:#"jeden.png"];
UIImage *bar = [UIImage imageNamed:#"dwa.png"];
UIImage *crown = [UIImage imageNamed:#"trzy.png"];
UIImage *cherry = [UIImage imageNamed:#"cztery.png"];
UIImage *lemon = [UIImage imageNamed:#"piec.png"];
UIImage *apple = [UIImage imageNamed:#"szesc.png"];
for (int i = 1; i <= 3; i++) {
UIImageView *sevenView = [[UIImageView alloc] initWithImage:seven];
UIImageView *barView = [[UIImageView alloc] initWithImage:bar];
UIImageView *crownView = [[UIImageView alloc] initWithImage:crown];
UIImageView *cherryView = [[UIImageView alloc] initWithImage:cherry];
UIImageView *lemonView = [[UIImageView alloc] initWithImage:lemon];
UIImageView *appleView = [[UIImageView alloc] initWithImage:apple];
NSArray *imageViewArray = [[NSArray alloc] initWithObjects:
sevenView, barView, crownView, cherryView, lemonView, appleView, nil];
NSString *fieldName = [[NSString alloc] initWithFormat:#"column%d", i];
[self setValue:imageViewArray forKey:fieldName];
//column1=[[NSArray alloc]initWithArray:imageViewArray];
//column2=[[NSArray alloc]initWithArray:imageViewArray];
//column3=[[NSArray alloc]initWithArray:imageViewArray];
[fieldName release];
[imageViewArray release];
[sevenView release];
[barView release];
[crownView release];
[cherryView release];
[lemonView release];
[appleView release];
//[picker selectRow: [self.column1 count] * (48 / 2) inComponent:i-1 animated:NO];
}
}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
NSString *arrayName = [[NSString alloc] initWithFormat:#"column%d", component+1];
NSArray *array = [self valueForKey:arrayName];
[arrayName release];
return [array objectAtIndex:row];
}
I think the problem might be in the way you're reusing views for your picker - you should not cache UIImageViews yourself (probably UIPickerView tries to use the same UIImageView in multiple places, so one of those places stays unoccupied).
Correct way will be to store UIImage instances and fill UIImageView that may be cached by picker. Boilerplate code (not tested):
- (void) viewDidLoad{
...
Here cache UIImages, not UIImageViews
...
}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
NSString *arrayName = [[NSString alloc] initWithFormat:#"column%d", component+1];
NSArray *array = [self valueForKey:arrayName];
[arrayName release];
UIImage *image = [array objectAtIndex:row];
if (!view){
view = [[[UIImageView alloc] init] autorelease];
}
[(UIImageView*)view setImage:image];
return view;
}
I keep getting this semantic issue with this code ('MyAnnotation' may not respond to 'initWithDictionary:'), im adding annotations to a map using a plist.
Even though it displays the pin and everything i want it to, i get an semantic issue and cant seem to solve the problem
if anyone could help that would be great thanks
heres the code, the problem is in the //BrewMapViewController.m the error is on this line
MyAnnotation *annotation = [[MyAnnotation alloc] initWithDictionary:breweryDict];
/*MyAnnotation.h*/
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface MyAnnotation : NSObject <MKAnnotation> {
CLLocationCoordinate2D coordinate;
NSString *title;
NSString *subtitle;
NSString *test;
}
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *subtitle;
#property (nonatomic, copy) NSString *test;
#end
/*MyAnnotation.m*/
#import "MyAnnotation.h"
#implementation MyAnnotation
#synthesize coordinate, title, subtitle, test;
- (id) initWithDictionary:(NSDictionary *) dict
{
self = [super init];
if (self != nil) {
coordinate.latitude = [[dict objectForKey:#"latitude"] doubleValue];
coordinate.longitude = [[dict objectForKey:#"longitude"] doubleValue];
self.title = [dict objectForKey:#"name"];
self.subtitle = [dict objectForKey:#"address"];
self.test = [dict objectForKey:#"test"];
}
return self;
}
#end
/*BrewMapViewController.h*/
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface BrewMapViewController : UIViewController <MKMapViewDelegate> {
IBOutlet MKMapView *map;
NSArray *breweries;
}
#end
/*BrewMapViewController.m*/
#import "BrewMapViewController.h"
#import "MyAnnotation.h"
#implementation BrewMapViewController
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
breweries = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:#"test"
ofType:#"xml"]];
double minLat = [[breweries valueForKeyPath:#"#min.latitude"] doubleValue];
double maxLat = [[breweries valueForKeyPath:#"#max.latitude"] doubleValue];
double minLon = [[breweries valueForKeyPath:#"#min.longitude"] doubleValue];
double maxLon = [[breweries valueForKeyPath:#"#max.longitude"] doubleValue];
MKCoordinateRegion region;
region.center.latitude = (maxLat + minLat) / 2.0;
region.center.longitude = (maxLon + minLon) / 2.0;
region.span.latitudeDelta = (maxLat - minLat) * 1.05;
region.span.longitudeDelta = (maxLon - minLon) * 1.05;
map.region = region;
for (NSDictionary *breweryDict in breweries){
MyAnnotation *annotation = [[MyAnnotation alloc] initWithDictionary:breweryDict];
[map addAnnotation:annotation];
[annotation release];
}
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
if (map.userLocation == annotation){
return nil;
}
NSString *identifier = #"MY_IDENTIFIER";
MKAnnotationView *annotationView = [map dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil){
annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:identifier]
autorelease];
annotationView.image = [UIImage imageNamed:#"beer.png"];
annotationView.canShowCallout = YES;
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
annotationView.leftCalloutAccessoryView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"pretzel.png"]] autorelease];
}
return annotationView;
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
NSLog(#"I've been tapped");
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)dealloc {
[breweries release];
[map release];
[super dealloc];
}
#end
You have to put the method signature for - (id) initWithDictionary:(NSDictionary *) dict into your header file in order to tell BrewMapViewController that the method exists:
/*MyAnnotation.h*/
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface MyAnnotation : NSObject <MKAnnotation> {
CLLocationCoordinate2D coordinate;
NSString *title;
NSString *subtitle;
NSString *test;
}
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *subtitle;
#property (nonatomic, copy) NSString *test;
- (id) initWithDictionary:(NSDictionary *) dict;
#end
Here's my issue, if I access this class with iOS 4.X, the code works fine.... however whenever I try to access it with iOS 5.0, I get nil values for the groups & assets. What's the best way to get this to work? I'm posting the entire class for a reference...
.h
#import <UIKit/UIKit.h>
#import <AssetsLibrary/AssetsLibrary.h>
#import "DejViewController.h"
#class Event, Venue;
#interface SelectMediaViewController : DejViewController <UITableViewDelegate, UITableViewDataSource> {
Event *event;
Venue *venue;
UITableView *tableView;
NSMutableArray *selectedAssets;
NSMutableArray *allMedia;
ALAssetsLibrary *library;
NSMutableArray *assetGroups;
}
#property (nonatomic, retain) Event *event;
#property (nonatomic, retain) Venue *venue;
#property (nonatomic, retain) IBOutlet UITableView *tableView;
#property (nonatomic, retain) NSMutableArray *allMedia;
#property (nonatomic, retain) NSMutableArray *assetGroups;
- (IBAction)continuePressed:(id)sender;
#end
.m
#import <ImageIO/ImageIO.h>
#import "SelectMediaViewController.h"
#import "CaptionAllMediaViewController.h"
#import "MediaItem.h"
#import "CLValueButton.h"
#import "SelectMediaTableViewCell.h"
#define kMediaGridSize 75
#define kMediaGridPadding 4
#define kSelectImageTag 828
#interface SelectMediaViewController(Private)
- (void)setContentForButton:(CLValueButton *)button withAsset:(ALAsset *)asset;
- (void)loadData;
#end
#implementation SelectMediaViewController
#synthesize event, venue;
#synthesize tableView;
#synthesize allMedia,assetGroups;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
selectedAssets = [[NSMutableArray alloc] init];
showNextButton = YES;
}
return self;
}
- (void)dealloc {
[tableView release];
[event release];
[venue release];
[library release];
[allMedia release];
[selectedAssets release];
[assetGroups release];
[super dealloc];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"SelectMediaViewController - viewDidLoad");
}
- (void)viewDidUnload {
NSLog(#"SelectMediaViewController - viewDidUnload");
[self setTableView:nil];
[super viewDidUnload];
}
- (void)viewDidAppear:(BOOL)animated {
NSLog(#"SelectMediaViewController - viewDidAppear");
[super viewDidAppear:animated];
[self setNavTitle:#"Select Media"];
[self loadData];
[self.tableView reloadData];
float contentOffset = self.tableView.contentSize.height - self.tableView.frame.size.height;
if (contentOffset < 0) contentOffset = 0;
[self.tableView setContentOffset:CGPointMake(0, contentOffset) animated:NO];
}
- (void)viewDidDisappear:(BOOL)animated {
NSLog(#"SelectMediaViewController - viewDidDisappear");
self.allMedia = nil;
[selectedAssets removeAllObjects];
[self.tableView reloadData];
}
- (void)loadData {
NSMutableArray *tempArray = [[NSMutableArray array] init];
library = [[ALAssetsLibrary alloc] init];
void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if(result != NULL) {
NSLog(#"See Asset: %#", result);
[tempArray addObject:result];
NSLog(#"assets count: %i", tempArray.count);
}
else {
NSLog(#"result nil or end of list");
}
};
void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) {
if(group != nil) {
[group enumerateAssetsUsingBlock:assetEnumerator];
NSLog(#"group: %#",group);
}
else {
NSLog(#"group nil or end of list");
}
if (stop) {
self.allMedia = [NSMutableArray arrayWithCapacity:[tempArray count]];
self.allMedia = tempArray;
NSLog(#"Loaded data: %d & %d", [tempArray count], [self.allMedia count]);
}
};
//ALAssetsLibrary *library = [[[ALAssetsLibrary alloc] init] autorelease];
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
usingBlock:assetGroupEnumerator
failureBlock:^(NSError *error) {
}];
//[library release];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (IBAction)continuePressed:(id)sender {
if ([selectedAssets count] > 0) {
CaptionAllMediaViewController *captionVC = [[CaptionAllMediaViewController alloc] initWithNibName:nil bundle:nil];
captionVC.event = self.event;
captionVC.venue = self.venue;
// Create media items
NSMutableArray *mediaItems = [NSMutableArray arrayWithCapacity:[selectedAssets count]];
for (ALAsset *asset in selectedAssets) {
MediaItem *item = [[MediaItem alloc] init];
item.asset = asset;
NSDictionary *metadata = [[asset defaultRepresentation] metadata];
NSDictionary *gpsMeta = [metadata objectForKey:#"{GPS}"];
if (gpsMeta) {
float latitude = [[gpsMeta objectForKey:#"Latitude"] floatValue];
if ([[gpsMeta objectForKey:#"LatitudeRef"] isEqualToString:#"S"]) latitude = latitude * -1;
float longitude = [[gpsMeta objectForKey:#"Longitude"] floatValue];
if ([[gpsMeta objectForKey:#"LongitudeRef"] isEqualToString:#"W"]) longitude = longitude * -1;
item.location = CLLocationCoordinate2DMake(latitude, longitude);
}
[mediaItems addObject:item];
[item release];
}
captionVC.media = mediaItems;
[self.navigationController pushViewController:captionVC animated:YES];
[captionVC release];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No Images Selected"
message:#"Please select at least one image to continue."
delegate:nil
cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
[alert release];
}
}
- (void)imagePressed:(CLValueButton *)sender {
BOOL currentlySelected = [selectedAssets containsObject:sender.valueObject];
UIImageView *imageView = (UIImageView *)[sender viewWithTag:kSelectImageTag];
if (!currentlySelected) {
[imageView setImage:[UIImage imageNamed:#"image-select-active.png"]];
[selectedAssets addObject:sender.valueObject];
} else {
[imageView setImage:[UIImage imageNamed:#"image-select.png"]];
[selectedAssets removeObject:sender.valueObject];
}
}
#pragma Table view methods
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"Getting table view count: %d", [self.allMedia count]);
if ([self.allMedia count] == 0) return 0;
return ceil([self.allMedia count] / 4.0);
}
- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 83;
NSLog(#"return83");
}
- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
SelectMediaTableViewCell *cell = (SelectMediaTableViewCell *)[_tableView dequeueReusableCellWithIdentifier:#"MEDIA_CELL"];
if (!cell) {
cell = [[[NSBundle mainBundle] loadNibNamed:#"SelectMediaTableViewCell" owner:nil options:nil] objectAtIndex:0];
// wire up selectors
[cell.image1 addTarget:self action:#selector(imagePressed:) forControlEvents:UIControlEventTouchUpInside];
[cell.image2 addTarget:self action:#selector(imagePressed:) forControlEvents:UIControlEventTouchUpInside];
[cell.image3 addTarget:self action:#selector(imagePressed:) forControlEvents:UIControlEventTouchUpInside];
[cell.image4 addTarget:self action:#selector(imagePressed:) forControlEvents:UIControlEventTouchUpInside];
}
int startIndex = indexPath.row * 4;
for (int i = 0; i < 4; i++) {
ALAsset *thisAsset = (startIndex + i) < [self.allMedia count] ? [self.allMedia objectAtIndex:startIndex + i] : nil;
CLValueButton *button = nil;
switch (i) {
case 0:
button = cell.image1;
break;
case 1:
button = cell.image2;
break;
case 2:
button = cell.image3;
break;
case 3:
button = cell.image4;
break;
default:
break;
}
[self setContentForButton:button withAsset:thisAsset];
UIImageView *imageView = (UIImageView *)[button viewWithTag:kSelectImageTag];
// letse see if it's selected or not...
if ([selectedAssets containsObject:button.valueObject]) {
[imageView setImage:[UIImage imageNamed:#"image-select-active.png"]];
} else {
[imageView setImage:[UIImage imageNamed:#"image-select.png"]];
}
}
return cell;
}
- (void)setContentForButton:(CLValueButton *)button withAsset:(ALAsset *)asset {
button.hidden = asset == nil;
if (asset) {
CGImageRef image = [asset thumbnail];
[button setImage:[UIImage imageWithCGImage:image] forState:UIControlStateNormal];
}
[button setValueObject:asset];
}
#pragma -
#end
Any help would be much appreciated, I've been trying to figure this out for 3 days...
The ALAssetsLibrary page in the online documentation now says "The lifetimes of objects you get back from a library instance are tied to the lifetime of the library instance."
I'm trying to put 2 UIPickerViews together in one ViewController. Each UIPickerView has different data arrays. I'm using interface builder to link the pickers up. I know I'll have to use separate delegates and dataSources but I can't seem to hook everything up with interface builder correctly. Here's all my code:
pickerTesting.h
#import <UIKit/UIKit.h>
#import "picker2DataSource.h"
#interface pickerTestingViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource>{
IBOutlet UIPickerView *picker;
IBOutlet UIPickerView *picker2;
NSMutableArray *pickerViewArray;
}
#property (nonatomic, retain) IBOutlet UIPickerView *picker;
#property (nonatomic, retain) IBOutlet UIPickerView *picker2;
#property (nonatomic, retain) NSMutableArray *pickerViewArray;
#end
pickerTesting.m
#import "pickerTestingViewController.h"
#implementation pickerTestingViewController
#synthesize picker, picker2, pickerViewArray;
- (void)viewDidLoad
{
[super viewDidLoad];
pickerViewArray = [[NSMutableArray alloc] init];
[pickerViewArray addObject:#" 100 "];
[pickerViewArray addObject:#" 200 "];
[pickerViewArray addObject:#" 400 "];
[pickerViewArray addObject:#" 600 "];
[pickerViewArray addObject:#" 1000 "];
[picker selectRow:1 inComponent:0 animated:NO];
picker2.delegate = self;
picker2.dataSource = self;
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)picker;
{
return 1;
}
- (void)pickerView:(UIPickerView *)picker didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
}
- (NSInteger)pickerView:(UIPickerView *)picker numberOfRowsInComponent:(NSInteger)component;
{
return [pickerViewArray count];
}
- (NSString *)pickerView:(UIPickerView *)picker titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{
return [pickerViewArray objectAtIndex:row];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload
{
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
And I have a separate class for the other datasource.
picker2DataSource.h
#interface picker2DataSource : NSObject <UIPickerViewDataSource, UIPickerViewDelegate>
{
NSMutableArray *customPickerArray;
}
#property (nonatomic, retain) NSMutableArray *customPickerArray;
#end
picker2DataSource.m
#import "picker2DataSource.h"
#implementation picker2DataSource
#synthesize customPickerArray;
- (id)init
{
// use predetermined frame size
self = [super init];
if (self)
{
customPickerArray = [[NSMutableArray alloc] init];
[customPickerArray addObject:#" a "];
[customPickerArray addObject:#" b "];
[customPickerArray addObject:#" c "];
[customPickerArray addObject:#" d "];
[customPickerArray addObject:#" e "];
}
return self;
}
- (void)dealloc
{
[customPickerArray release];
[super dealloc];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)picker2;
{
return 1;
}
- (void)pickerView:(UIPickerView *)picker2 didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
}
- (NSInteger)pickerView:(UIPickerView *)picker2 numberOfRowsInComponent:(NSInteger)component;
{
return [customPickerArray count];
}
- (NSString *)pickerView:(UIPickerView *)picker2 titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{
return [customPickerArray objectAtIndex:row];
}
#end
Any help or code examples would be great. Thanks.
Using Interface Builder, set the tag properties of the two UIPickerViews to 1 and 2, respectively. Then, in each delegate method, use if statements to check the tag of the UIPickerView argument.
How about UIPickerViewDataSource method
//This returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 2;
}
I'm looking to pass a user chosen value from one view to the next so it can be submitted to Twitter, Facebook, etc.
Would a global variable be best to implement? I don't want the value to be stored or saved anywhere.. just to make it through the end of the navigation controller (submission to Facebook, Twitter, etc.)
Any suggestions? Thanks in advance.
Header File
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "ShareViewController.h"
#include "TwitterRushViewController.h"
#interface KindViewController : UIViewController <UIPickerViewDelegate, UIScrollViewDelegate, CLLocationManagerDelegate> {
IBOutlet UIScrollView *scrollView;
IBOutlet UIPageControl *pageControl;
BOOL pageControlIsChangingPage;
CLLocationManager *locationManager;
NSString *finalCoordinates;
NSString *finalChoice;
}
#property (nonatomic, retain) UIView *scrollView;
#property (nonatomic, retain) UIPageControl *pageControl;
#property (nonatomic, retain) CLLocationManager *locationManager;
#property (retain) NSString *finalCoordinates;
#property (nonatomic, copy) NSString *finalChoice;
-(IBAction)changePage:(id)sender;
-(IBAction)submitChoice:(id)sender;
-(void)setupPage;
#end
Implementation File
#import "KindViewController.h"
#import "JSON/JSON.h"
#implementation KindViewController
#synthesize scrollView;
#synthesize pageControl;
#synthesize locationManager;
#synthesize finalCoordinates;
#synthesize finalChoice;
#pragma mark -
#pragma mark UIView boilerplate
- (void)viewDidLoad {
[self setupPage];
[super viewDidLoad];
// Alert the User on Location Access
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self;
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
}
-(void)viewWillAppear:(BOOL)animated {
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
CLLocation *location = newLocation;
NSLog(#"Our current Latitude is %f", location.coordinate.latitude);
NSLog(#"Our current Longitude is %f", location.coordinate.longitude);
NSString *Coordinates = [[NSString alloc] initWithFormat: #"Longitude=%f&Latitude=%f", location.coordinate.longitude, location.coordinate.latitude ];
NSLog(#"Test: %#", Coordinates);
finalCoordinates = Coordinates;
[locationManager stopUpdatingLocation];
}
#pragma mark -
#pragma mark The Guts
- (void)setupPage {
scrollView.delegate = self;
[scrollView setCanCancelContentTouches:NO];
scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView.clipsToBounds = YES;
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
NSUInteger nimages = 0;
CGFloat cx = 0;
for (; ; nimages++) {
NSString *imageName = [NSString stringWithFormat:#"choice%d.png", (nimages + 1)];
UIImage *image = [UIImage imageNamed:imageName];
if (image == nil) {
break;
}
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
CGRect rect = imageView.frame;
rect.size.height = image.size.height;
rect.size.width = image.size.width;
rect.origin.x = ((scrollView.frame.size.width - image.size.width) / 2) + cx;
rect.origin.y = ((scrollView.frame.size.height - image.size.height) / 2);
imageView.frame = rect;
[scrollView addSubview:imageView];
[imageView release];
cx += scrollView.frame.size.width;
}
self.pageControl.numberOfPages = nimages;
[scrollView setContentSize:CGSizeMake(cx, [scrollView bounds].size.height)];
}
#pragma mark -
#pragma mark UIScrollViewDelegate stuff
- (void)scrollViewDidScroll:(UIScrollView *)_scrollView {
if (pageControlIsChangingPage) {
return;
}
CGFloat pageWidth = _scrollView.frame.size.width;
int page = floor((_scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
pageControl.currentPage = page;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)_scrollView {
pageControlIsChangingPage = NO;
}
#pragma mark -
#pragma mark PageControl stuff
- (IBAction)changePage:(id)sender {
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * pageControl.currentPage;
frame.origin.y = 0;
[scrollView scrollRectToVisible:frame animated:YES];
pageControlIsChangingPage = YES;
}
-(IBAction)submitChoice:(id)sender; {
// Spinner
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(135,140,50,50)];
[spinner startAnimating];
[self.view addSubview:spinner];
// Find the Date
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:#"MMM dd, yyyy HH:mm"];
NSDate *now = [[NSDate alloc] init];
NSString *dateString = [format stringFromDate:now];
// Echo Everything
NSLog(#"Type is %f.", scrollView.contentOffset.x);
NSLog(#"Date is %#", dateString);
NSLog(#"Coordinates are %#", finalCoordinates);
NSString *completeURL = [[NSString alloc] initWithFormat: #"http://www.example.com/insert.php?Type=%f&Time=%#&%#", scrollView.contentOffset.x, dateString, finalCoordinates];
NSString *escapedUrl = [completeURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"URL is %#.", escapedUrl);
// Post to Web Server
NSURL *urlToSend = [[NSURL alloc] initWithString:escapedUrl];
NSLog(#"NSURL is %#.", urlToSend);
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:urlToSend cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:30];
NSData *urlData;
NSURLResponse *response;
NSError *error;
urlData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];
// Do the Button Action
ShareViewController *shareViewController = [[ShareViewController alloc] initWithNibName:#"ShareViewController" bundle:nil];
shareViewController.finalChoice = #"Facebook Property";
[self.navigationController pushViewController:shareViewController animated:YES];
[shareViewController release];
[urlToSend release];
[completeURL release];
[spinner release];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(#"There is an error updating the location");
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
[super viewDidUnload];
[pageControl release];
}
- (void)dealloc {
[super dealloc];
}
#end
ShareViewController.h
#import <UIKit/UIKit.h>
#import "MapViewController.h"
#import "SA_OAuthTwitterController.h"
#import "FBConnect/FBConnect.h"
#import "TwitterRushViewController.h"
#import "oAuth2TestViewController.h"
#class SA_OAuthTwitterEngine;
#interface ShareViewController : UIViewController <UITextFieldDelegate, SA_OAuthTwitterControllerDelegate> {
}
#property (nonatomic, retain) IBOutlet UIButton *shareFacebookBTN;
#property (nonatomic, retain) IBOutlet UIButton *shareTwitterBTN;
#property (nonatomic, retain) KindViewController finalChoice;
/* Submissions */
- (IBAction)shareNoThanks:(id)sender;
- (IBAction)shareFacebook:(id)sender;
- (IBAction)shareTwitter:(id)sender;
#end
Just setting a property on the next UIViewController when you push it would probably be the easiest thing to do.
SomeViewController *someViewController = [[SomeViewController alloc] init];
someViewController.facebookProperty = #"Facebook Property";
someViewController.twitterProperty = #"Twitter Property";
[self.navigationController pushViewController:someViewController animated:YES];
[someViewController release];
Ok there are a few things wrong with ShareViewController.h. First if you have a property you also need to have an instance variable for that property. Next you are assigning a string to finalChoice but you have declared its type as KindViewController it should be NSString.
In ShareViewController.h
#interface ShareViewController : UIViewController <UITextFieldDelegate, SA_OAuthTwitterControllerDelegate> {
NSString *finalChoice;
}
#property (nonatomic, retain) IBOutlet UIButton *shareFacebookBTN;
#property (nonatomic, retain) IBOutlet UIButton *shareTwitterBTN;
#property (nonatomic, copy) NSString *finalChoice;
And make sure you #synthesize finalChoice in your implementation file.
Without knowing any of the specifics, I would avoid a global variable or tightly coupling the two views together.
Depending on your needs and implementation, delegation or notifications may a better choice to pass a variable between views.
There's a good discussion on the more general problem of how best to communicate between view controllers over here. The top-voted answer is pretty good.
The tl;dr version is basically:
Global variables and singleton classes are rarely the right answer.
Read up on the "dependency injection" design pattern.
Hope that helps.