How to bring the custom view cell above table rows in NSTableView? - objective-c

When I use a custom view as the cell of a view-based NSTableView, the custom view is somewhat below the table row. When I click on it, instead of affecting the elements (e.g. text field) custom view, the table row was selected (and highlighted). I have to reclick to select the text field.
- (NSView*)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
NSLog(#"We are creating views!");
NSTableCellView *newView;
newView = [tableView makeViewWithIdentifier:#"PostCell" owner:self];
NSTextField *newTextField = [[NSTextField alloc] init];
[newView addSubview:newTextField];
return newView;
}
When I disable the row selection according to NSTableView - Disable Row Selection, there was no selection.
- (BOOL)selectionShouldChangeInTableView:(NSTableView *)tableView {
return NO;
}
But I still cannot select directly the text field. What's worse, I cannot even select it using the mouse. Only tab on the keyboard works.
There seem to be something above it. But is it the "table column" shown in interface builder? Or something else?
How can I fix this?

Use a custom subclass of NSTableView and override -validateProposedFirstResponder:forEvent: to return YES.
See this blog entry from the Apple engineer who wrote the view-based table view code.

Make sure following code is present.
- (BOOL)tableView:(NSTableView *)aTableView shouldSelectRow:(NSInteger)rowIndex {
return YES;
}
You may try logging the subviews Or you can check superviews of view.
This will help to understand view hierarchy.
Also on side note if one of the view's userInteraction is disable then it's subview's won't be able to receive the events. Please verify that all the views and it's subviews userInteraction is enable.
I hope this helps.

Related

Hide button in NSTableView

I am a little stuck and can't seem to work this out from the apple docs.
I have two buttons in an NSTable column, contained within an NSTableCellView.
I am trying to, in code, hide the button depending on the values of the object in the row.
Getting the values is fine, but i can't work out how to target the specific button, i can't bind it to an outlet as it's within a table. I have tried the below code, but that just hides the entire NSTableCellView rather than the specific button, i have also tried changing the identifier to be of the button, but that seems to do the same.
if(selectedTweet.imageURL){
NSButton *imageButton = [tableView makeViewWithIdentifier:#"secondButtons" owner:self];
[imageButton setHidden:NO];
return imageButton;
} else {
NSButton *imageButton = [tableView makeViewWithIdentifier:#"secondButtons" owner:self];
[imageButton setHidden:YES];
return imageButton;
}
This is obviously much simpler than i am making it?? Help greatly appreciated.
Thanks
Gareth
If you are using CocoaBindings to populate that table, you can just bind the button's "Hidden" attribute to Table Cell View/objectValue.imageURL and use the NSIsNil value transformer. No code needed at all.
If you are using an old-fashioned data source, things become a tad more complicated. In that case you could have a imageButton property in your object, and set it in the NSTableViewDelegate's - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row method.

How do I re-use my custom UITableViewCell in various UITableView?

I have three separate "UIViewControllers" in my app. Each has UITableView attached to it.
First UITableView displays just a single table of rows of data (news items).
Second UITableView displays a search view, which has a few sections where users type in different search criteria.
Third UITableView displays the article details.
In each of the UITableView, there is a button.
First UITableView has "Load more articles" button.
Second UITableView has "Search" button
Third UITableView has "Visit article page" button.
Since all three views are UITables, I created a custom UITableCellView and added to each of the UITableViews. Here's an example of my "ButtonCell" in the 2nd UITableView
ButtonCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ButtonCell"];
NSString *cellText = #"Search";
[[cell buttonLabel] setText:cellText];
return cell;
This works well - exactly how I want it.
Now I added the same "ButtonCell" to the first and third UITableView, but a few strange things happened.
The background color of the ButtonCell is not correct - in the ButtonCell ".xib" file, I set it to a blue-ish color. This works well for the 2nd UITableView, but for others, it's just "white".
The ButtonCell doesn't have "rounded corners" anymore.
Any ideas on how to properly "re-use" my custom button cell in any UITableViews?
It sounds like your second table is grouped, and the other two plain (you get rounded corners with a grouped table view style). Setting the color of custom cells in IB for plain tables doesn't work. You should set the color of your cells in the tableView:willDisplayCell:forRowAtIndexPath: delegate method:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
cell.backgroundColor = [UIColor colorWithRed:.67 green:.93 blue:1 alpha:1];
}

TableView with dynamically height

I'm programming on objective-c. I have a viewController with tableView. I would like that my tableView has a dynamically height like on a picture below (Tweetbot). How can I make it?
Yes. However its not clear that this table is "short" - it may be that it has a transparent background and only two cells. In any case, to make a short table you would create a UIViewController class with a normal view (ie a UIView). Create a UIImageView and add the image to it (assuming you want a big image), and add that to the view (you could do this in IB). Then create a UITableView of the desired height, and add that too to the UIIView's subviews. Now you have a container view (self.view) with two subviews, the table being the last (so its on top).
Most likly tweetbot doesn't add a UITableView upon a UIViewController. They most likely use the UITableViewController from scratch, giving it a background and (in this case) showing only two cells with a custom height. That is also the "way-2-go" when using the Table View.
You should use -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath method and use if condition or switch case in this method.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row ==2) {
return 89;//write your image view's height here.
}
return 44;
}

make custom UIView become first responder in custom UITableViewCell

I have three UITableViewCell subclasses. I'm displaying these in a table view in a view controller. I have, in the view controller, returning nil for tableView:willSelectRowAtIndexPath: since I want the UITextFields, in two of my UITableViewCell subclasses, to get focus and become first responder.
For the third UITableViewCell subclass, I have a custom UIView subclass that houses a UIWebView. Currently the div in the html content loaded in the UIWebView is one line tall. I previously made the div height 100% but found that scrolling started to act up. If I tap in the div the keyboard comes up. However, if the user taps any where else within this custom UITableViewCell the UIWebView div is not selected and the keyboard does not come up.
How can I get either my custom UITableViewCell or custom UIView subclass to become the first responder? Or am I going about this the wrong way?
I believe you're going about this the wrong way. Returning nil for tableView:willSelectRowAtIndexPath: won't really help your cause here.
Instead, you have a couple options. First, you could make a UIButton that sits behind your text fields in your table cell which fills the entire view, and then respond to touches on it and tell the text field to become active. Like so:
Wire up the button within your UITableViewCell subclass:
[self.button addTarget:self action:#selector(handleTouch) forControlEvents:UIControlEventTouchUpInside];
Set focus on the text field when touched:
- (void)handleTouch
{
[self.textField becomeFirstResponder];
}
The other option, and the one I like less, is to handle the selection of the cell in the delegate methods and tell the cell's textfield to become active. Like so:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCellSubclass *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell.textField becomeFirstResponder];
}
In which of course you would need to add a textField property to your MyCustomCellSubclass in order to do this.
Hope this helps!

Adding Text Field Data to Table Cell

How I can store text field data in a view controller into a tableView cell in a TableViewController With Xcode using data source?
That means when the user taps "+" it will show another view that has the text field. When the user enters the text and presses save, the entered data will be stored as a table cell.
First make sure you understand data sources. Then you have to implement
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return self.data.count;
}
- (NSView *)tableView:(NSTableView *)tableView
viewForTableColumn:(NSTableColumn *)tableColumn
row:(NSInteger)row {
NSTableCellView * result = [tableView makeViewWithIdentifier:#"identifier" owner:self];
result.textField = #"Your special string";
return result;
}
After having setup it in IB like this and having connected the outlet of the Table View data source to your custom objects class (the class the above code is in) it should look like this
Please notice I used the same identifier as in the code so that I can get the created table cell view back easily.
self.data could be an array for example in which you store all your underlying objects (for the cell creation).
Of course you could also add any kind of UI elements to the cell view as well. In this case I use a custom subclass for the cell view. You would have to do something like this then (and set your class as the class of the cell view within IB of course. This is the part in the screenshot that has an NSTableCellView currently in it. It had to be MyGreatCellView from now on):
#interface MyGreatCellView : NSTableCellView {
IBOutlet NSTextField *files;
}
#property (assign) NSTextField *files;
Then you could also refer to result.files in the tableView:vieForTableColumn:row for example.
If something is unclear, just ask.
Getting the UITextField data onto a TableView Cell.
Here is a query for some one for the same issue.I think it will help you.