UIPickerView with one object - xcode

I am using a UIPickerView and currently their is only a single object in it. How can I display that single object on label.
It has this weird property that when we use pickerView the data is not set selected by default.Once we choose another object or roll it, then only any particular object is selected. Hence if only one object is their in pickerView. It does not count as selected even though when you tap on that single object.
I tried a lot but found that if their are more than one object then only you can display the selected object on label but not if their is only one object.

You need to make a code that is triggered when the UIPickerView changes, like this:
#pragma
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
//Action that triggers following code:
{
NSString *nameString = [nameOnMutubaleArrayYouWannaGetDataFrom objectAtIndex:[picker selectedRowInComponent:0]]; //Or 1 if u have multiple rows
NSString *labelString = [[NSString alloc]initWithFormat:
#" %# ", nameString];
labelOutput.text = labelString;
Hope this helps.

Related

Separate NSPopUpButton content from label while using bindings

I have an NSPopupButton whose content is bound to an NSArray, let’s say the array is
#[
#"Option 1",
#"Option 2"
];
Its selected object is bound to User Defaults Controller, and is written to a preference file by the user defaults system.
In my code I check whether the preference is set to #"Option 1" or not, and perform actions accordingly.
This all worked well (though I did feel a little uneasy checking for what is essentially a UI value, but whatever...) until I needed to localize.
Because the value is the label, I’m having an issue.
If my user is in France, his preferences file will say #"L’option 1", which is not equal to #"Option 1". I need to abstract the presentation from the meaning and it's proving pretty difficult.
I split up the binding into two arrays, let's call them values and labels.
Let’s say they look like this:
values = #[
#"option_1",
#"option_2"
];
labels = #[
NSLocalizedString(#"Option 1", nil),
NSLocalizedString(#"Option 2", nil)
];
I’ve bound the NSPopUpButton’s Content binding to values and its Content Values binding to labels. However, the popup list is showing option_1 and option_2, it does not seem to want to use the labels array to label the items in the popup button.
How do I get the NSPopUpButton to use values internally and store that in the preferences file, but display labels to the user?
It doesn’t have to be architected this way, if you can think of a better solution. The point is I want to store and check one value, and have that value associated with a label that gets localized appropriately.
Cocoa bindings work very well with value transformers, because you can apply them directly in the bindings window, for example
#implementation LocalizeTransformer
+ (Class)transformedValueClass
{
return [NSArray class];
}
+ (BOOL)allowsReverseTransformation
{
return NO;
}
- (id)transformedValue:(id)value {
if (![value isKindOfClass:[NSArray class]]) return nil;
NSMutableArray *output = [NSMutableArray arrayWithCapacity:[value count]];
for (NSString *string in value) {
[output addObject:NSLocalizedString(string, nil)];
}
return [output copy];
}
#end
you have to register the transformer in awakeFromNib or better in +initialize
NSValueTransformer *localizeTransformer = [[LocalizeTransformer alloc] init];
[NSValueTransformer setValueTransformer:localizeTransformer
forName:#"LocalizeTransformer"];
then it appears in the popup menu of value transformers
Bind Selected Tag to your User Defaults Controller instead of Selected Object.
If the NSPopupButton choices are fixed add the NSMenuItems in Interface Builder and set their Tags. Otherwise bind an array of NSMenuItem, again with proper Tags.
Selected Index would also work but only until you change the order.

Sorting NSTableView

I have two coloumn in NSTableView as Name and Salary with 5-10 values. I want to sort these coloumn after click on header of both the column. There is lots of data present in Internet but I am not able to use these. Please help me to do this in cocoa.
Thanks in advance and appreciate any help.
Each table column has a method setSortDescriptorPrototype
Sort descriptors are ways of telling the array how to sort itself (ascending, descending, ignoring case etc.)
Iterate over each of the columns you want as sortable and call this method on each of those columns, and pass the required sort descriptor (In my case I'll be using the column identifier)
for (NSTableColumn *tableColumn in tableView.tableColumns ) {
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:tableColumn.identifier ascending:YES selector:#selector(compare:)];
[tableColumn setSortDescriptorPrototype:sortDescriptor];
}
After writing this piece of initialization code, NSTableViewDataSource has a method - (void)tableView:(NSTableView *)aTableView sortDescriptorsDidChange:(NSArray *)oldDescriptors that notifies you whenever a sort descriptor is changed, implement this method in the data source and send a message to the data array to sort itself
- (void)tableView:(NSTableView *)aTableView sortDescriptorsDidChange:(NSArray *)oldDescriptors
{
self.data = [self.data sortedArrayUsingDescriptors:sortDescriptors];
[aTableView reloadData];
}
This method will get fired each time a column header is clicked, and NSTableColumn shows a nice little triangle showing the sorting order.
I stumbled upon this question while looking for the easiest way of implementing something similar. Although the original question is old, I hope someone finds my answer useful! Please note that I am using Xcode 5.1.1
Ok so to do this you need to:
select the actual column you want to sort in your table.
In your Attributes Inspector you need to fill in two fields: Sort Key, and Selector.
In the Sort Key field, you need to enter the value of your Identifier. The value of your Identifier is located in your Identity Inspector.
In the Selector field you need to enter a suitable selector method based on the object type in the column. The default method is; compare:
Based on the Table View Programming Guide for Mac. The compare: method works with NSString, NSDate, and NSNumber objects. If your table column contains only strings, you may want to consider using the caseInsensitiveCompare: method if case sensitivity is unimportant. However, consider replacing these method signatures with the localizedCompare: or localizedCaseInsensitiveCompare: methods to take into the account the user’s language requirements.
Finally, you need to declare the tableView:sortDescriptorsDidChange: method in your Table View Controller in the format shown below:
-(void)tableView:(NSTableView *)mtableView sortDescriptorsDidChange:(NSArray *)oldDescriptors
{
[listArray sortUsingDescriptors: [mtableView sortDescriptors]];
[tableView reloadData];
}
Just had lately the same issue to get tableView sorted.
My approach :
bind your sortDescriptors to tableview's arrayController
bind tableview's sortDescriptors to Arraycontroller's sort descriptor
perform the settings in attribute inspector (see Tosin's answer above)
Worked perfect for me. No need to set prototypes for columns or something else.
Thanks very much ,It is usefullly for my question.
my code like this
First, set unique values in the XIB interface,like name...
- (void)viewDidLoad {
[super viewDidLoad];
self.itemTableView.dataSource = self;
self.itemTableView.delegate = self;
self.itemTableView.selectionHighlightStyle = NSTableViewSelectionHighlightStyleRegular;
self.itemTableView.usesAlternatingRowBackgroundColors = YES;
for (NSTableColumn *tableColumn in self.itemTableView.tableColumns ) {
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:tableColumn.identifier ascending:NO selector:#selector(compare:)];
[tableColumn setSortDescriptorPrototype:sortDescriptor];
}
}
-(void)tableView:(NSTableView *)tableView sortDescriptorsDidChange:(NSArray<NSSortDescriptor *> *)oldDescriptors{
NSLog(#"sortDescriptorsDidChange:%#",oldDescriptors);
[self.itemArr sortUsingDescriptors:[tableView sortDescriptors]];
[self.itemTableView reloadData];
}

NSTableView rowViewAtRow: always returning nil

I'm trying to display an NSPopover with additional information to a selected row of an NSTableView. For that I need to get a reference to the view representation of the selected row so I can "attach" my popover to it:
NSInteger row = [[self membersTableView] selectedRow];
NSTableRowView *aView = [[self membersTableView] rowViewAtRow: row makeIfNecessary: YES];
[self setQuickLookPopoverController: [QuickLookPopoverController showPopoverFor: anObject at: aView]];
In the above, the result of aView is always nil. According to Apple documentation, this is the method to obtain a view object, given a selected row. Especially the last sentence of the discussion is a bit weird:
Discussion This method will first attempt to return a currently
displayed view in the visible area. If there is no visible view, and
makeIfNecessary is YES, a prepared temporary view is returned. If
makeIfNecessary is NO, and the view is not visible, nil will be
returned.
In general, makeIfNecessary should be YES if you require a resulting
view, and NO if you only want to update properties on a view only if
it is available (generally this means it is visible).
An exception will be thrown if row is not within the numberOfRows. The
returned result should generally not be held onto for longer than the
current run loop cycle. It is better to call
rowViewAtRow:makeIfNecessary: whenever a view is required..
Why is this method always returning nil?
Solved it. I used NSTableView's method (NSRect) rectOfRow: (NSInteger) rowIndex which will give the frame of the required row.
Thanks for showing me the right direction, I had the same problem! I ended up doing the following, but note that I disabled selection of empty rows and that the following code is inside an IBAction:
[popOver showRelativeToRect:[sender bounds]
ofView:[sender rowViewAtRow:[sender selectedRow]
makeIfNecessary:YES]
preferredEdge:NSMaxXEdge];

View Based Table Cells on OS X not showing data properly

So I admit to being a total noob to cocoa, so I offer a noob question. I'm probably just missing the dumb obvious somewhere but i just cant seem to get my table to populate data.
I'm following the table view playground example but everytime i try to mimic the Basic TableView Window the first row becomes the height of the number of rows i added (at least thats what it looks like. Here is my code:
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row
{
NSString *identifier = [tableColumn identifier];
if ([identifier isEqualToString:#"filename"]) {
// We pass us as the owner so we can setup target/actions into this main controller object
NSTableCellView *cellView = [fileBrowserTable makeViewWithIdentifier:identifier owner:self];
// Then setup properties on the cellView based on the column
cellView.textField.stringValue = [fileList filenameAtIndex:row];
cellView.imageView.objectValue = [[NSWorkspace sharedWorkspace] iconForFile:[fileList fullPathAtIndex:row]];
return cellView;
}
else if ([identifier isEqualToString:#"path"]) {
NSTextField *textField = [fileBrowserTable makeViewWithIdentifier:identifier owner:self];
textField.objectValue = [fileList pathAtIndex:row];
return textField;
}
else if ([identifier isEqualToString:#"preview"]) {
NSTextField *textField = [fileBrowserTable makeViewWithIdentifier:identifier owner:self];
textField.objectValue = [fileList previewAtIndex:row];
return textField;
}
return nil;
}
I think its worth mentioning that when using a the old school text field cell, I have no problems displaying data (of course the above code is different in that case) so im positive sure its not a problem with my data structure that holds the values. I have also set the correct delegate and data source
The cell using the 'filename' identifier uses the 'image and text table view cell' while the others use just a 'text table cell view'. Neither of them work so i'm guessing something is wrong with how I set my table up. But when comparing my table with that of the example, it's just a spitting reflection (minus identifiers file names).
One thing that I notice that I can't quite figure out is that the example says:
The NSTableView has two reuse identifier assocations: "MainCell" and "SizeCell" are both associated with the nib ATBasicTableViewCells.xib
I don't really understand this statement. However that being said, the example doesn't contain any ATBasicTableViewCells.xib nor does it have any associations with it (code or ib) that I can find.
Have you tried to set the rowSizeStyle of the NSTableView to NSTableViewRowSizeStyleCustom?
[UPDATE] Re-reading your question, it's not clear for me what your problem is. The solution I have given is related to problems with the size of each cell which is not taken into account unless the rowSizeStyle is set to custom.

Binding to NSTextField Cell not working, edited value resets to default

I'm working on a Core Data document application that dynamically creates NSTableColumns. The data cell type may be a checkbox, slider, etc. Programmatically binding to all cell types works, except for NSTextFieldCell.
All NSTextFieldCells fail to bind, and after editing they return to their default value. This happens no matter if they're binding to a string, a number (with an NSNumberFormatter applied), or a date (NSDateFormatter applied). I'm using the following format to do all bindings:
NSDictionary *textFieldOpts = [NSDictionary dictionaryWithObjectsAndKeys:#"YES", NSContinuouslyUpdatesValueBindingOption, #"YES", NSValidatesImmediatelyBindingOption, nil];
[aCell bind:#"value" toObject:[[entryAC arrangedObjects] objectAtIndex:0] withKeyPath:#"numberData" options:textFieldOpts];
Again, these statements work if the cell type is anything but an NSTextFieldCell.
I threw in an -observeValueForKeyPath method to log when the value changes... and for other cell types (NSSliderCell for instance) I can see the value changing, but with the NSTextFieldCell, it never, ever updates.
Turns out that I needed to implement the NSTableView data source method setObjectValue to manually get the change from the NSTableView (View) and then manually set the data in the array controller (Model) similar to the code below:
- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {
[[[entryAC arrangedObjects] objectAtIndex:rowIndex] setValue:(NSNumber *)anObject forKey:#"numberData"];
}
For some reason, the bindings to NSTextFieldCells, when set programmatically on a cell-by-cell basis, only work one way: to display the data only. Personally I would classify this as a bug...

Resources