I'm new to Cocoa/Objective-c so please bear with me on this.
I'm trying to create a simple program that has a TableView on the left of the window and a CustomView on the right. The TableView has 3 columns: (NSString) name, (NSInteger) x, (NSInteger) y. The x and y values are randomly generated between 0 and 100 whenever a new row is added. I have a simple Star class to hold these three attributes. The TableView seems to be working just fine.
On the right, I have a CustomView where I want to load an image whenever a new row is added to the tableview at the x,y for that entry.
I created this "addStar" method in the CustomView class, which is an NSView. Then, in my TableViewController class, I'm trying to call the "addStar" method in my "add" method that adds a new row.
When I launch the program, I'm able to add items to the TableView, but nothing shows up in the CustomView. Any ideas of where I'm going wrong here?
CustomView.m
#import "CustomView.h"
#implementation CustomView
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
- (void)drawRect:(NSRect)dirtyRect
{
NSBezierPath* path = [NSBezierPath bezierPathWithRect:self.bounds];
[[NSColor whiteColor] setFill];
[path fill];
}
- (void)addStar:(float)x and:(float)y
{
NSRect rect = NSMakeRect(x, y, 35, 35);
imageView = [[NSImageView alloc] initWithFrame:rect];
[imageView setImageScaling:NSScaleNone];
[imageView setImage:[NSImage imageNamed:#"star.png"]];
[self addSubview:imageView];
}
#end
TableViewController.m
#import "TableViewController.h"
#import "CustomView.h"
#import "Star.h"
#implementation TableViewController
- (id)init
{
self = [super init];
if (self) {
list = [[NSMutableArray alloc] init];
}
return self;
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return [list count];
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
Star *s = [list objectAtIndex:row];
NSString *identifier = [tableColumn identifier];
return [s valueForKey:identifier];
}
- (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
Star *s = [list objectAtIndex:row];
NSString *identifier = [tableColumn identifier];
[s setValue:object forKey:identifier];
}
// Add row to the tableview
- (IBAction)add:(id)sender {
Star *star = [[Star alloc] init];
[list addObject:star];
[tableView reloadData];
// add star to the custom view
CustomView* cv = [[CustomView alloc] init];
[cv addStar:(float)[star xCoordinate] and:(float)[star yCoordinate]];
[star release];
}
- (IBAction)remove:(id)sender {
NSInteger row = [tableView selectedRow];
[tableView abortEditing];
if (row != -1)
[list removeObjectAtIndex:row];
[tableView reloadData];
}
- (void)dealloc
{
[list release];
[super dealloc];
}
#end
On right side you have Custom view And also you are creating new one as below...
CustomView* cv = [[CustomView alloc] init];
[cv addStar:(float)[star xCoordinate] and:(float)[star yCoordinate]];
But you are not adding this cv object on the screen.
write,
[self addSubview:cv];//add this below above code as you are creating new object each time.
My below code working fine in below iOS 7
I am trying to add picker view in alert that works fine in below ios7 version But in ios 7 it show white alert without picker view.
-(void)showPinPickerAlert
{
numberarr = [[NSMutableArray alloc]initWithObjects:#"0",#"1",#"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9", nil];
UIAlertView *alert =[[UIAlertView alloc]initWithTitle:#"Enter Pin To Change Track me Option" message:#"\n\n\n\n\n\n\n" delegate:self cancelButtonTitle:#"Verify" otherButtonTitles:nil];
UIPickerView *picker=[[UIPickerView alloc]initWithFrame:CGRectMake(25, 30, 230, 60) ];
picker.dataSource=self;
picker.delegate=self;
// picker.backgroundColor=[UIColor blueColor];
picker.showsSelectionIndicator = YES;
// picker.autoresizingMask = UIViewAutoresizingFlexibleHeight;
picker.transform = CGAffineTransformMakeScale(0.6, 0.6);
alert.tag=100;
// picker.transform = CGAffineTransformMakeScale(1, 0.2);
[alert addSubview:picker];
[alert show];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
{
return 4;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
strPin=[[NSString stringWithFormat:#"%i%i%i%i",[pickerView selectedRowInComponent:0],[pickerView selectedRowInComponent:1],[pickerView selectedRowInComponent:2],[pickerView selectedRowInComponent:3]]mutableCopy];
NSLog(#"strPin=%#",strPin);
// mlabel.text= [arrayNo objectAtIndex:row];
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
{
return [numberarr count];
}
**//code try to change color of picker text and background thats work fine in below ios7 but in iOS 7 still shows white screen**
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
UILabel *label = (UILabel*) view;
if (label == nil)
{
label = [[UILabel alloc] init];
}
//[label setText:#"Whatever"];
// This part just colorizes everything, since you asked about that.
[label setTextColor:[UIColor whiteColor]];
[label setBackgroundColor:[UIColor blackColor]];
CGSize rowSize = [pickerView rowSizeForComponent:component];
CGRect labelRect = CGRectMake (0, 0, rowSize.width, rowSize.height);
[label setFrame:labelRect];
return label;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{
pickerView.backgroundColor=[UIColor blackColor];
return [numberarr objectAtIndex:row];
}
OutPut in below
Output in IOS 7
How to fix it?
Adding subviews to a UIAlertView is not supported anymore, starting in iOS7.
You should implement your own view and try to do it similar to the alert view, or like other person said, use a 3rd party alert view like this one:
https://github.com/wimagguc/ios-custom-alertview
Most of the following code is from pre ios7 stack overflow answers.
PickerPrompt.h
#import <UIKit/UIKit.h>
#interface PickerPrompt : UIAlertView <UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate>
{
UIPickerView *_pickerView;
NSMutableArray *_options;
}
#property (readonly) NSString *enteredText;
- (id)initWithTitle:(NSString *)title message:(NSString *)message options:(NSMutableArray*)options delegate:(id)delegate cancelButtonTitle:(NSString *)cancelButtonTitle okButtonTitle:(NSString *)okButtonTitle;
#end
pickerPrompt.m
#import "PickerPrompt.h"
#implementation PickerPrompt
#define VIEW_TAG 49
#define SUB_LABEL_TAG 52
#define LABEL_TAG 53
#define COMPONENT_WIDTH 250
#define LABEL_WIDTH 10
#synthesize enteredText;
- (id)initWithTitle:(NSString *)title message:(NSString *)message options:(NSMutableArray*)options delegate:(id)delegate cancelButtonTitle:(NSString *)cancelButtonTitle okButtonTitle:(NSString *)okayButtonTitle
{
if (self = [super initWithTitle:title message:message delegate:delegate cancelButtonTitle:cancelButtonTitle otherButtonTitles:okayButtonTitle, nil])
{
_options = options;
_pickerView = [[UIPickerView alloc] init];
[_pickerView sizeToFit];
[_pickerView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
[_pickerView setDelegate:self];
[_pickerView setDataSource:self];
[_pickerView setShowsSelectionIndicator:TRUE];
// Change from pre iOS 7
[self setAlertViewStyle:UIAlertViewStylePlainTextInput];
[[self textFieldAtIndex:0] setDelegate:self];
[[self textFieldAtIndex:0] setInputView:_pickerView];
[[self textFieldAtIndex:0] becomeFirstResponder];
}
return self;
}
#pragma mark -
#pragma mark Picker delegate
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
if (pickerView == _pickerView) {
return [_options count];
}
return [_options count];
}
- (UIView *)labelCellWithWidth:(CGFloat)width rightOffset:(CGFloat)offset {
// Create a new view that contains a label offset from the right.
CGRect frame = CGRectMake(0.0, 0.0, width, 32.0);
UIView *view = [[[UIView alloc] initWithFrame:frame] autorelease];
view.tag = VIEW_TAG;
frame.size.width = width - offset;
UILabel *subLabel = [[UILabel alloc] initWithFrame:frame];
subLabel.textAlignment = UITextAlignmentRight;
subLabel.backgroundColor = [UIColor clearColor];
subLabel.font = [UIFont systemFontOfSize:24.0];
subLabel.userInteractionEnabled = NO;
subLabel.tag = SUB_LABEL_TAG;
[view addSubview:subLabel];
[subLabel release];
return view;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *fullString = [[textField text] stringByAppendingString:string];
for (NSString* object in _options) {
if ([object isEqualToString:fullString]) {
return YES;
}
}
return NO;
}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
UIView *returnView = nil;
if ((view.tag == VIEW_TAG) || (view.tag == LABEL_TAG)) {
returnView = view;
}
else {
returnView = [self labelCellWithWidth:COMPONENT_WIDTH rightOffset:LABEL_WIDTH];
}
// The text shown in the component is just the number of the component.
NSString *text = [_options objectAtIndex:row];
// Where to set the text in depends on what sort of view it is.
UILabel *theLabel = nil;
if (returnView.tag == VIEW_TAG) {
theLabel = (UILabel *)[returnView viewWithTag:SUB_LABEL_TAG];
}
else {
theLabel = (UILabel *)returnView;
}
theLabel.text = text;
return returnView;
}
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
return COMPONENT_WIDTH;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
[[self textFieldAtIndex:0] setText:[_options objectAtIndex:row]];
}
- (NSString *)enteredText
{
return [[self textFieldAtIndex:0] text];
}
#end
How to use (called from an alert view delegate):
PickerPrompt *prompt = [PickerPrompt alloc];
NSMutableArray *options = [[NSMutableArray alloc] initWithObjects:#"option 1", #"option 2", nil];
prompt = [prompt initWithTitle:#"Select Option" message:#"Select Option" options:options delegate:self cancelButtonTitle:#"Cancel" okButtonTitle:#"Okay"];
[prompt show];
[prompt release];
I'm building an app with two UI textFields. When the UI textfields are touched a UI Picker comes up for the user to select a value to stay in the UI textField. When I test the app and touch one UI TextView and scroll the UI Picker, both UI textFields change values. Meaning, each UI Text Field is being affected from each UI Picker. Anyone know why? Thank you.
#interface ViewController () <UIPickerViewDataSource, UIPickerViewDelegate>
#end
#implementation ViewController
#synthesize ageTextField;
#synthesize relationshipTextField;
#synthesize resultLabel;
#synthesize calculateButton;
#synthesize agePickerView;
#synthesize relationshipPickerView;
#synthesize ageArray;
#synthesize relationshipArray;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//age pickerView
self.agePickerView = [[UIPickerView alloc]init];
self.agePickerView.delegate = self;
self.agePickerView.dataSource = self;
self.agePickerView.showsSelectionIndicator = YES;
self.ageTextField.inputView = self.agePickerView;
self.ageArray = #[ #"1", #"2", #"3", #"4", #"5", #"5", #"6", #"7", #"8", #"9", #"10", #"11", #"12"
, #"13", #"14", #"15", #"16", #"17", #"18", #"19", #"20", #"21", #"22", #"23", #"24", #"25", #"26", #"27", #"28", #"29", #"30", #"31", #"32", #"33", #"34", #"35", #"36", #"37", #"38", #"39", #"40", #"41", #"42", #"43", #"44", #"45", #"46", #"47", #"48", #"49", #"50", #"51", #"52", #"53", #"54", #"55", #"56", #"57", #"58", #"59", #"60", #"61", #"62", #"63", #"64", #"65", #"66", #"67", #"68", #"69", #"70", #"71", #"72", #"73", #"74", #"75", #"76", #"77", #"78", #"79", #"80", #"81", #"82", #"83", #"84", #"85", #"86", #"87", #"88", #"89", #"90", #"91", #"92", #"93", #"94", #"95", #"96", #"97", #"98", #"99", #"100" ];
[self pickerView:self.agePickerView
didSelectRow:0
inComponent:0];
//relationship pickerView
self.relationshipPickerView = [[UIPickerView alloc]init];
self.relationshipPickerView.delegate = self;
self.relationshipPickerView.dataSource = self;
self.relationshipPickerView.showsSelectionIndicator = YES;
self.relationshipTextField.inputView = self.relationshipPickerView;
self.relationshipArray = #[ #"1", #"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9",#"10",#"11",#"12",#"13", #"14",#"15",#"16",#"17",#"18",#"19",#"20",#"21",#"22",#"23",#"24",#"25", #"26",#"27",#"28",#"29",#"30",#"31",#"32",#"33",#"34",#"35",#"36",#"37", #"38",#"39",#"40",#"41",#"42",#"43",#"44",#"45",#"46",#"47",#"48",#"49",#"50", #"51", #"52", #"53", #"54", #"55", #"56", #"57", #"58", #"59", #"60", #"61", #"62", #"63", #"64", #"65", #"66", #"67", #"68", #"69", #"70", #"71", #"72", #"73", #"74", #"75", #"76", #"77", #"78", #"79", #"80", #"81", #"82", #"83", #"84", #"85", #"86", #"87", #"88", #"89", #"90", #"91", #"92", #"93", #"94", #"95", #"96", #"97", #"98", #"99", #"100"];
[self pickerView:self.relationshipPickerView
didSelectRow:0
inComponent:0];
}
-(int) numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
-(int) pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [self.ageArray count];
return [self.relationshipArray count];
}
-(NSString *) pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return [self.ageArray objectAtIndex:row];
return [self.relationshipArray objectAtIndex:row];
}
-(void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent: (NSInteger)component{
self.ageTextField.text = [self.ageArray objectAtIndex:row];
self.relationshipTextField.text = [self.relationshipArray objectAtIndex:row];
}
- (void)viewDidUnload
{
[self setAgeTextField:nil];
[self setRelationshipTextField:nil];
[self setResultLabel:nil];
[self setCalculateButton:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#end
-(int) pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [self.ageArray count];
return [self.relationshipArray count];
}
That's not how C (or Objective-C) works. It will always only execute the first line.
You need to conditionalize the return value based on which UIPickerView is asking for the information:
if (pickerView == self.agePickerView) {
return [self.ageArray count];
} else {
return [self.relationshipArray count];
}
And then apply that same pattern to all the datasource methods.
Im really close on this one...For the purposes of this i have two text boxes. when pressed they invoke a ui picker.
text box one returns values 1,2,3,4
text box two returns values A, B, C, D
The problem is that when the picker is presented for text box two it shows the values from text box one, although will select the appropriate row from text box two. Could someone check over my code and tell me where im making an error, thanks.
.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate,UITextFieldDelegate>
{
//decalre picker
UIPickerView *select;
//declare NSArrray
NSArray *arrStatus;
NSArray *arrStatus2;
}
#property (strong, nonatomic) IBOutlet UITextField *text1;
- (IBAction)Value:(id)sender;
#property (strong, nonatomic) IBOutlet UITextField *text2;
#end
.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize text2;
#synthesize text1;
- (void)viewDidLoad
{
select = [[UIPickerView alloc] initWithFrame:CGRectZero];
select.delegate = self;
select.dataSource = self;
[select setShowsSelectionIndicator:YES];
text1.inputView = select;
text2.inputView = select;
arrStatus = [[NSArray alloc] initWithObjects:#"1",#"2",#"3",#"4",nil];
arrStatus2 = [[NSArray alloc] initWithObjects:#"A",#"B",#"C",#"D",nil];
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
//One column
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
//set number of rows
return arrStatus.count;
return arrStatus2.count;
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
//set item per row
return [arrStatus objectAtIndex:row];
return [arrStatus2 objectAtIndex:row];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[self setText1:nil];
[self setText2:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (IBAction)Value:(id)sender {
NSInteger selectedRow = [select selectedRowInComponent:0];
if([text1 isFirstResponder])
text1.text = [arrStatus objectAtIndex: selectedRow];
[text1 resignFirstResponder];
if ([text2 isFirstResponder])
text2.text = [arrStatus2 objectAtIndex: selectedRow];
[text2 resignFirstResponder];
}
#end
So to sum up im trying to get, 1 picker view, with 1 colum, 2 arrays, 2 text boxes. Ive tried creating another picker view and that didnt work either
The return statement exits the method. Therefore , if you have 2 return statements , it will never get to the second one. You should modify these methods as such:
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if([text1 isFirstResponder])
return arrStatus.count;
else
return arrStatus2.count;
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if([text1 isFirstResponder])
return [arrStatus objectAtIndex:row];
else
return [arrStatus2 objectAtIndex:row];
}
Hope this helps. Cheers!
This is Code Which is able to show picker view with the given array and textfield will have the first data of the UIPickerView.Please let me know if you have any issue.I did it for one textfield for next textfield you just need to figure out using tag of textfield and set the Text.
-(void)viewDidLoad
{
[super viewDidLoad];
arrayNo = [[NSArray alloc] initWithObjects:#"1",#"2",#"3",#"4",nil];
[pickerView selectRow:1 inComponent:0 animated:NO];
self.text1.text= [arrayNo objectAtIndex:[pickerView selectedRowInComponent:0]];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
{
return 1;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
mlabel.text= [arrayNo objectAtIndex:row];
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
{
return [arrayNo count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{
return [arrayNo objectAtIndex:row];
}
I have a problem with my pickerview where by clicking on the textfield it shows an empty uipickerview. I have 3 textfield where by clicking on each textfield there will be different array for each one.
Here's the code:
- (void)viewDidLoad
{
[super viewDidLoad];
tbMode.inputView = pickerView;
tbWalkDist.inputView = pickerView;
tbRouteOpt.inputView = pickerView;
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
-(void)textFieldDidBeginEditing:(UITextField*)textField;
{
modeArray = [[NSMutableArray alloc] init];
if(textField.tag==1){
[modeArray addObject:#" A "];
[modeArray addObject:#" B "];
pickerView.hidden = NO;
}
else{
if(textField.tag==2){
[modeArray addObject:#" 300 "];
[modeArray addObject:#" 400 "];
[modeArray addObject:#" 500 "];
pickerView.hidden = NO;
}
else{
if(textField.tag==3){
[modeArray addObject:#" cheapest "];
[modeArray addObject:#" fastest "];
pickerView.hidden = NO;
}
else{
pickerView.hidden=YES;
}
}
}
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
{
return 1;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent: (NSInteger)component
{
tbMode.text = [modeArray objectAtIndex:row];
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
{
return [modeArray count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{
return [modeArray objectAtIndex:row];
}
pls help! where did i got wrong? is it possible that this method -(void)textFieldDidBeginEditing:(UITextField*)textField; is not called? thanks
edit* i miss out these 3 line of line which is for each textfield which use to call that method in viewDidLoad
tbMode.delegate = self;
tbWalkDist.delegate = self;
tbRouteOpt.delegate = self;
But I'm still getting an empty picker view. how can i add these NSMutableArray into the the picker view
*add in [pickerView reloadAllComponents]; the picker will display the values :)
I don't see here where you initialize the pickerView ivar. Can I assume it is created in xib?
If so, make sure you have connected the iBOutlet and set up its delegate and datasource property to be the "file owner" or view controller as it were.
If you create the picker in the init method, post that code so we can see if those properties are set correctly.
You also must have set your controller as the delegate for the uiTextField.
Additionally, if they are not implemented elsewhere, you are missing these required protocols:
– pickerView:rowHeightForComponent:
– pickerView:widthForComponent:
As for your output problem, you need to keep track of the uiTextField that activated. Add an ivar,
uiTextField *activeField;
set the variable to the appropriate uiTextField object in the textfield delegate method. Then replace,
tbMode.text = [modeArray objectAtIndex:row];
with,
activeField.txt = [modeArray objectAtIndex:row];
Set the ivar like so:
-(void)textFieldDidBeginEditing:(UITextField*)textField
{
activeField = textField;
// all the if else logic here
}
Try [pickerView reloadAllComponents] after setting the new data set.