I have a table view with several cells, each containing a UITextView.
The user can edit each text view that he clicks.
But when he clicks DONE, how do I access each text view, to read each that was edited?
You can use UItextField delegate to get the text from current text filed as -
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
NSString *textFieldValue = [textField text];
}
Let's say your UITextView is called "tv"
You can use something like:
NSString *contents = tv.text;
I believe you can also use something along the lines of:
NSString *contents = [tv getText];
Related
I've been using a NSTextView to display some non-editable text and would like to highlight any links within it's string. I've seen some code that parses out the links and adds attributes. That would work fine, but I was wondering if I could somehow reuse the built-in link detection somehow.
I've tried setting:
[textView setEnabledTextCheckingTypes:NSTextCheckingTypeLink];
[textView setAutomaticLinkDetectionEnabled:YES];
and using:
[textView checkTextInDocument:nil];
after setting the string.
For the sake of completeness, here is how I've manually added links to a NSTextView:
- (void)highlightLinksInTextView:(NSTextView *)view {
NSDataDetector *linkDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil];
NSArray *matches = [linkDetector matchesInString:view.string options:0 range:NSMakeRange(0, view.string.length)];
[view.textStorage beginEditing];
for (NSTextCheckingResult *match in matches) {
if (!match.URL) continue;
NSDictionary *linkAttributes = #{
NSLinkAttributeName: match.URL,
};
[view.textStorage addAttributes:linkAttributes range:match.range];
}
[view.textStorage endEditing];
}
Unfortunately you have to call this every time you set the NSTextView string.
I recently stumbled upon this and created an NSTextView subclass, LinkDetectingTextView.swift. Hope this helps someone in the future.
I'm using an NSOutlineView with source list style, and using the view based (rather than cell based) outline view.
I would like to be able to make some rows bold. However, my attempts to change the font (manually in IB, through code in viewForTableColumn:…, or through the Font Bold binding) have so far been ignored.
From this message, it appears that this is because the source list style for NSOutlineView takes over managing the text field's appearance:
I'm guessing that you've hooked up your text field to the textField outlet of the NSTableCellView? If so, I think you might be running into NSTableView's automatic management of appearance for source lists.
Try disconnecting the text field from the textField outlet and see if your custom font sticks.
If I disconnect the textField outlet, the appearance does come under my control, and my emboldening works.
However, now I can't get it to look like the automatic one. By which I mean, when NSOutlineView was managing the text field's appearance, the font was bold and gained a drop shadow when any item was selected, but when I'm managing it manually this is not the case.
Can anyone answer either of these questions:
How can I get the Font Bold binding to work when NSOutlineView is managing the appearance of my text field
If I don't have NSOutlineView manage the appearance of my text field, how can I make it look and behave like it would if I did have it manage it?
I think I found the solution:
NSTableCellView manages the appearance of it's textField outlet by setting the backgroundStyle property on cells of contained controls. Setting this to NSBackgroundStyleDark triggers a special path in NSTextFieldCell which essentially sets an attributedStringValue, changing the text color and adding an shadow via NSShadowAttributeName.
What you could do is two things:
Set the backgroundStyle on your own in a custom row or cell view subclass.
Use a custom NSTextFieldCell in the cell's text field and change the behavior/drawing.
We did the latter since we needed a different look for a themed (differently colored) table view. The most convenient (albeit surely not most efficient) location we found for this was to override - drawInteriorWithFrame:inView: and modify the cell's attributed string before calling super, restoring the original afterwards:
- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
NSAttributedString *originalString = self.attributedStringValue;
// Customize string as you like
if (/* whatever */)
[self setAttributedStringValue: /* some string */];
// Regular drawing
[super drawInteriorWithFrame:cellFrame inView:controlView];
// Reset string
if (self.attributedStringValue != originalString)
self.attributedStringValue = originalString;
}
In the hope this may help others in similar situations.
Not sure if I have missed anything in your question but changing the font using the following works for me. ReminderTableCellView is just a subclass of NSTableCellView with an additional dateField added.
- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
//LOG(#"viewForTableColumn called");
// For the groups, we just return a regular text view.
if ([_topLevelItems containsObject:item]) {
//LOG(#" top level");
NSTableCellView *result = [outlineView makeViewWithIdentifier:#"HeaderCell" owner:self];
// Uppercase the string value, but don't set anything else. NSOutlineView automatically applies attributes as necessary
NSString *value = [item uppercaseString];
[result.textField setStringValue:value];
//[result.textField setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
return result;
} else {
//LOG(#" menu item");
// The cell is setup in IB. The textField and imageView outlets are properly setup.
// Special attributes are automatically applied by NSTableView/NSOutlineView for the source list
ReminderTableCellView *result = [outlineView makeViewWithIdentifier:#"DataCell" owner:self];
if ([item isKindOfClass:[OSTreeNode class]]) {
[result.textField setFont:[NSFont boldSystemFontOfSize:13]];
result.textField.stringValue = [item displayName];
result.dateField.stringValue = [item nextReminderDateAsString];
}
else
result.textField.stringValue = [item description];
if (_loading)
result.textField.textColor = [NSColor grayColor];
else
result.textField.textColor = [NSColor textColor];
NSImage *image = [NSImage imageNamed:#"ReminderMenuIcon.png"];
[image setSize:NSMakeSize(16,16)];
[result.imageView setImage:image];
//[result.imageView setImage:nil];
return result;
}
}
Resulting view is shown below. Note this is is an NSOutlineView with Source Listing option selected but I can't see why this would'nt work for a normal outlineView.
I have Table View controller, then it has subclass DetailViewController, which content changes depending on cell chosen, but when move on, and from my DetailViewController go to MapView, I try to use same method I used to get text on DetailViewController, but it dont works, no matter what I do. Im stuck with it more like 3 week now:(
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!self.detailViewController) {
self.detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
[self.navigationController pushViewController:self.detailViewController animated:YES];
[self.detailViewController changeProductText:[teksti objectAtIndex:indexPath.row]];
[self.detailViewController changeProductText1:[adrese objectAtIndex:indexPath.row]];
[self.detailViewController changeProductText2:[laimigastunda objectAtIndex:indexPath.row]];
[self.detailViewController changeImage:[imageChange objectAtIndex:indexPath.row]];
}
}
No matter what I change here, it dont work.
It looks from the code you are showing that you are not giving a data object to your detailViewController, but rather set directly the values.
This is not the way to do it and probably the reason why you are having issues. You need to grasp the concept of MVC and go back to it.
At least you should
1. build a dictionary in first view with keys #"teksti", #"adrese", #"longitude", #latitude".
2. Create a property in DetailViewController to hold the dictionary.
3. update the values displayed when displaying the DetailViewController
So that when you press the map button, you can then push a view containing a mapView and set the map to the latitude and longitude that you have.
So it would do:
NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:[teksti objectAtIndex:indexPath.row], #"teksti", [adrese objectAtIndex:indexPath.row], #"adrese", [latitude objectAtIndex:indexPath.row], #"latitude", [longitudes objectAtIndex:indexPath.row], #"longitude", nil];
[detailViewController setDict:dict];
and in the DetailViewController.m:
- (void)viewWillAppear:(BOOL)animated{
[self changeProductText:[dict objectForKey:#"teksti"]];
.... And so on
}
Your code will be useful to provide you with more details directions.
I am trying to set multiple labels with identical text and cannot for the life of me figure out the proper way of doing so.
I am using an ibaction to handle a switch that will either change several labels in a collection to say "yes" or "no" and have been trying both a for loop and makeobjectsperformselector withobject method, but so far no luck.
Any insight would be greatly appreciated.
You can set the tag of UILabel subviews to help you out with this. If it's not already set, go to the storyboard, click on your label, go to the Attributes Inspector and under "View" there's a tag field.
If the labels all have different tags (0,1,2...) , the following loop should do what you need:
for(UIView *subview in [self.view subviews] ) {
if([subview isKindOfClass:[UILabel class]]) {
UILabel *currentLabel = (UILabel *)[self.view viewWithTag:subview.tag];
currentLabel.text = #"yes";
}
}
I want to show an NSPopover from an NSToolbarItem button in my toolbar.
(i.e. positioned below the button).
Ideally, I want to pass the NSView of the button to the popover to position it.
My question is, how do I get the NSView of the NSToolbarItem?
[toolbarbutton view] always returns nil.
The answer appears to be in the video for the 2011 WWDC Session 113, "Full Screen and Aqua Changes." Basically, put an NSButton inside the NSToolbaritem and use the view of that.
A blog post is here: http://www.yellowfield.co.uk/blog/?p=33, and a sample project is on github at http://github.com/tevendale/ToolbarPopover
All in the sprit of http://xkcd.com/979!
You can send the action directly from the NSButton enclosed in the NSToolbarItem (which is what you should generally do anyways, consider segmented controls, where each segment has its own target/action), and that will do the trick.
Instead of getting the view from the IBAction sender, connect an IBOutlet directly to the toolbar item and use that to get the relative view:
In your header file:
#property (weak) IBOutlet NSToolbarItem *theToolbarItem;
#property (weak) IBOutlet NSPopover *thePopover;
In your implementation file, to show the popover:
[self.thePopover showRelativeToRect:[[self.theToolbarItem view] bounds] ofView:[self.theToolbarItem view] preferredEdge:NSMinYEdge];
This will also work for showing popups from menu item selections inside a toolbar item.
While I did achieve that the Popover was shown using the approach mentioned by Stuart Tevendale, I did run into problems when I tried to validate (enable / disable) the NSToolbarItems using the NSToolbarDelegate:
-(BOOL)validateToolbarItem:(NSToolbarItem *)toolbarItem {
BOOL enable = YES;
NSString *identifier = [toolbarItem itemIdentifier];
// This does never get called because I am using a button inside a custom `NSToolbarItem`
if ([identifier isEqualToString:#"Popover"]) {
return [self someValidationMechanism];
}
// For this the validation works when I am using a standard `NSToolbarItem`
else if ([identifier isEqualToString:#"StandardToolbarItem"]){
return [self someOtherValidationMechanism];
}
return enable;
}
So I would advise not to display a Popover from NSToolbarItem. An alternative might be to show a Page Sheet: How to show a NSPanel as a sheet