I am at loss as far as why there is a corruption in the below code. I pretty much lifted the existing "implementation" from examples. Still, when I try to change the value of my picker controller, code crashes because cloudProviders points to some random memory.
Please advise.
// SettingsViewController.h
#import <UIKit/UIKit.h>
#interface SettingsViewController : UIViewController
<UIPickerViewDelegate, UIPickerViewDataSource>
#property (retain, nonatomic) IBOutlet UIPickerView *picker;
#property (retain, nonatomic) NSArray *cloudProviders;
#end
// SettingsViewController.m
#import "SettingsViewController.h"
#interface SettingsViewController ()
#end
#implementation SettingsViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_cloudProviders = #[#"BOX", #"Yandex", #"Other"];
NSLog(#"Executing viewDidLoad");
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)dealloc {
[_picker release];
[super dealloc];
}
#pragma mark -
#pragma mark PickerView DataSource
- (NSInteger)numberOfComponentsInPickerView:
(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
return _cloudProviders.count;
}
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
return _cloudProviders[row];
}
#pragma mark -
#pragma mark PickerView Delegate
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{
NSLog(#"Executing didSelectRow");
}
/*
-(IBAction)textFieldReturn:(id)sender
{
[sender resignFirstResponder];
}
*/
#end
Also, what tools do people use to track down memory leaks and such on iOS? Is there something that could tell me who modified my pointer?
Thank you
Anna is correct.
Setting the property as self.cloudProviders solves the problem.
Related
I added a UIPickerView to a UITableViewCell. I am adding about 5 entries to it. Now when I try to select a value, the - (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component function is called with the correct row. But on the scrren the UIPickerView "scrolls" back to the first element and does not stick to the selected value.
Anyone had the same problem?
EventSelectCell.h
#class EventSelectCell;
#protocol EventSelectCellDelegate <NSObject>
- (void)selectedEvent:(Event*)selectedEvent;
#end
#interface EventSelectCell : UITableViewCell <UIPickerViewDataSource, UIPickerViewDelegate>
#property (strong, nonatomic) id <EventSelectCellDelegate> delegate;
#property (weak, nonatomic) IBOutlet UIPickerView *selectWheel;
#end
EventSelectCell.m
#import "EventSelectCell.h"
#implementation EventSelectCell
{
EventManager* eventManager;
NSArray* listOfEvents;
}
- (void)awakeFromNib {
self.selectWheel.delegate = self;
self.selectWheel.dataSource = self;
// get the EventManger
eventManager = [EventManager sharedEventManager];
listOfEvents = [eventManager getListOfEvents];
[self.selectWheel reloadAllComponents];
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
return [listOfEvents count];
}
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
Event* selectedEvent = [listOfEvents objectAtIndex:row];
return [selectedEvent name];
}
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
Event* selectedEvent = [listOfEvents objectAtIndex:row];
[self.delegate selectedEvent:selectedEvent];
}
#end
the delegate
- (void)selectedEvent:(Event*)selectedEvent {
[playersInGame removeAllObjects];
[playersInGame addObjectsFromArray:[self.eventManager getPlayersInEvent:selectedEvent onlyActive:YES]];
[selectedEvent setIsActive:[NSNumber numberWithInt:1]];
activeEvent = selectedEvent;
[self.tableView reloadData];
}
Okay, I found the problem. The UIPickerView is in a UITableViewCell. Whenever someone selected something with the UIPickerView I called [self.tableView reloadData], this caused the table to reload and also initialized the UIPickerView again.
Now I am just reloading a singel section in the table.
I am trying to use a PickerView with ARC turned off, it has become a nightnmare, will be extremely grateful if someone could please have a quick look kindly suggest how to solve...thnx in advance
the issue is that the rest of my app is non-arc and so i want to add the pickerview as a class that can operate as a viewcontroller in the project...
I had multiple pickers working beautifully 4 days ago with arc but when i turned arc off it became a nightmare...to identify the precise issue i have removed all the frills and am just working with a bare structure now....there are no errors but the data from the array is not displaying...i am listing the header and omplementation files below...the reason i had linked the folder was to make the interface file available....so that the connections can be checked too...but we can look at that after the basic code is first checked....thanks so much for your kind attention and time...
.h
#import <UIKit/UIKit.h>
#interface HomeViewController : UIViewController UIPickerViewDataSource,UIPickerViewDelegate>
{NSArray *categoryTypes;
}
#property (retain, nonatomic) IBOutlet UIPickerView *categoryTypePicker;
#property (retain, nonatomic) IBOutlet UIButton *categoryTypeBtn;
#end
.m
#import "HomeViewController.h"
#interface HomeViewController ()
#define kPICKER1COLUMN 1
#define kCATEGORYTYPEPICKERTAG 21
#define kCATEGORYTYPEBTN 31
#end
#implementation HomeViewController
#synthesize categoryTypeBtn;
#synthesize categoryTypePicker;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
categoryTypes = [[NSArray alloc] initWithObjects:#"Appetizers",#"Breakfast",#"Dessert",#"Drinks",
#"Main Dish/Entree", #"Salad", #"Side Dish", #"Soup", #"Snack",
#"Baby Food", #"Pet Food", nil];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
categoryTypePicker.tag = kCATEGORYTYPEPICKERTAG;
categoryTypePicker.showsSelectionIndicator = TRUE;
categoryTypePicker.dataSource = self;
categoryTypePicker.delegate = self;
self.categoryTypePicker.dataSource = self;
self.categoryTypePicker.delegate = self;
[self.categoryTypePicker reloadAllComponents];
categoryTypePicker.hidden = YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (int)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
if (pickerView.tag == kCATEGORYTYPEPICKERTAG)
return kPICKER1COLUMN;
else { return 0; }
}
- (int)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (pickerView.tag == kCATEGORYTYPEPICKERTAG)
return [categoryTypes count];
else { return 0; }
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (pickerView.tag == kCATEGORYTYPEPICKERTAG)
return [categoryTypes objectAtIndex:row];
else { return 0; }
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (pickerView.tag == kCATEGORYTYPEPICKERTAG)
{
NSString *categoryType = [categoryTypes objectAtIndex:[categoryTypePicker selectedRowInComponent:0]];
[categoryTypeBtn setTitle:categoryType forState:UIControlStateNormal];
NSLog(#"%#", categoryType);
}
pickerView.hidden=YES;
}
-(IBAction) showCategoryTypePicker{
{
[self.view addSubview:categoryTypePicker];
categoryTypePicker.hidden = NO;
}
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)dealloc {
[categoryTypes release];
[categoryTypePicker release];
[super dealloc];
}
#end
i will await your reply...
linktocode
[dont have access to comments so am responding here] thanks rdelmar i commented out the init-bundle and the subview of the button but now the build is giving the error bad access...i have a rough idea of what is going on but don't know how to address it...the issue is basically that the array is not retained for the objectAtIndex call...need some way of retaining it...thnx
I want to display a list of peoples in an UITableView (I write the name in the ViewController and display them as a list in the UITableViewController).
I just need to stock up the data. But my code add just one object in the NSMutableArray.
Is it because I use a singleton in my class "Customers"?
This is my code so far:
Customers.h
#import <Foundation/Foundation.h>
#interface Customers : NSObject
{
NSString *name;
float age;
}
- (id)initWithName:(NSString *)aname age:(float)aage ;
- (NSString*) name;
- (float) age;
- (void) setName:(NSString*) newName;
- (void) setAge:(float) newAge;
+(Customers*)instance;
#end
Customers.m
#import "Customers.h"
#implementation Customers
- (id)initWithName:(NSString *)aname age:(float)aage {
if ((self = [super init]))
{
self.name = aname;
age = aage;
}
return self;
}
- (NSString*) name{
return name;
}
- (float) age{
return age;
}
- (void) setName:(NSString*) newName
{
name = newName;
}
- (void) setAge:(float) newAge{
age = newAge;
}
+(Customers*)instance{
static dispatch_once_t once;
static Customers *sharedInstance;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] initWithName:#"jean" age:24];
});
return sharedInstance;
}
#end
ViewController.h
#import <UIKit/UIKit.h>
#class Customers;
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet UITextField *nameLabel;
#property (strong, nonatomic) IBOutlet UITextField *ageLabel;
- (IBAction)goToTableView:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#import "Customers.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)goToTableView:(id)sender {
[[Customers instance] setName:_nameLabel.text];
}
#end
TableViewController.h
#import <UIKit/UIKit.h>
#class Customers;
#interface TableViewController : UITableViewController
{
NSMutableArray *peopleListe;
}
#end
TableViewController.m
#import "TableViewController.h"
#import "Customers.h"
#interface TableViewController ()
#end
#implementation TableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
Customers *koko = [[Customers alloc ] initWithName:[[Customers instance]name] age:[[Customers instance]age]];
peopleListe = [NSMutableArray arrayWithObjects: nil];
[peopleListe addObject: koko];
NSLog(#"%#",peopleListe);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return peopleListe.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:#"MyBasicCell"];
Customers *list = [peopleListe objectAtIndex:indexPath.row];
cell.textLabel.text = list.name;
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return NO;
}
#end
Thank you for your help in advance.
According to your comment, you want to add an object every time the controller gets loaded.
- (void)viewDidLoad {
[super viewDidLoad];
Customers *koko = [[Customers alloc ] initWithName:[[Customers instance] name]
age:[[Customers instance] age]];
peopleListe = [NSMutableArray arrayWithObjects: nil];
[peopleListe addObject: koko];
NSLog(#"%#",peopleListe);
}
I see multiple problems with this:
I'm not sure viewDidLoad is the correct method to embed this in, i don't think it is guaranteed to get called if the view is already in memory. (I don't have any ios experience, so I'm not sure.) It might even be that your controller gets removed and created from scratch every time you use it.
You replace your whole list when you allocate peopleList. You should check for its existence and only allocate it if it does not exist yet. (Obj-C initializes instance variables as nil, so a simple check is enough.)
Apart from that, you seem to mix controller and model code. If you have the time you should look into moving the array into the model and out of the controller code.
here's my code that I am using now but still getting all kinds of errors:
No visible #interface for 'HomeViewController' declares the selector 'getCount'
And
/Volumes/Lex/HomeViewController.h:12:12: Required for direct or indirect protocol 'UIPickerViewDataSource'
/Volumes/Lexar/HomeViewController.m:15:17: Incomplete implementation
My code (.m file)
- (void)viewDidLoad
{
[super viewDidLoad];
PFUser *currentUser = [PFUser currentUser];
if (currentUser) {
NSLog(#"Current user: %#" , currentUser.username);
}
else {
[self performSegueWithIdentifier:#"showLogin" sender:self];
self.pickerView.dataSource = self;
self.pickerView.delegate = self;
}
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent: (NSInteger)component
{
if ([self getCount] == 0)
return 1;
return [self getCount];
}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent: (NSInteger)component reusingView:(UIView *)view {
if ([self getCount] == 0)
return nil;
}
- (IBAction)logout:(id)sender {
[PFUser logOut];
[self performSegueWithIdentifier:#"showLogin" sender:self];
}
#end
And the header
/// .h controller
#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#interface HomeViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate>
#property (strong, nonatomic) IBOutlet UIPickerView *pickerView;
- (IBAction)logout:(id)sender;
#end
As you mentioned in your comment, you are just placing UIPickerView...but for using picker view you need to set Datasource like UITableView and have to implement all #required methods.
In picker view's data source protocol, there are 2 #required methods
// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
So you need to implement above two method in your controller (say MainViewController). and don't forget to set this class as delegate and datasource to UIPicker view as below
in ViewDidLoad of MainViewController
self.yourPickerView.datasource = self;
self.yourPickerView.delegate = self;
I just updated my project to ios6 and discovered that my UIPicker is no longer displaying the data in it. I really don't know what I could do to make sure that it does again. Any suggestions?
AddRoleTVC.h
#import <UIKit/UIKit.h>
#interface AddRoleTVC : UITableViewController <UIPickerViewDataSource, UIPickerViewDelegate> {
IBOutlet UIPickerView *pickerView;
NSMutableArray *arrayColors;
}
#end
AddRoleTVC.m
#import "AddRoleTVC.h"
#import "UIAlertView+error.h"
#import "API.h"
#include <CommonCrypto/CommonDigest.h>
#implementation AddRoleTVC
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
arrayColors = [[NSMutableArray alloc] init];
[arrayColors addObject:#"Red"];
[arrayColors addObject:#"Orange"];
[arrayColors addObject:#"Yellow"];
[arrayColors addObject:#"Green"];
[arrayColors addObject:#"Blue"];
[arrayColors addObject:#"Indigo"];
[arrayColors addObject:#"Violet"];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
return [arrayColors count];
}
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [arrayColors objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSLog(#"Selected Color: %#. Index of selected color: %i", [arrayColors objectAtIndex:row], row);
}
#end
You used the IBOutlet To Picker View, so You set Delegate and datasource in your .Xib File. It must work.