UITextInput setMarkedText:selectedRange not working? (Can't be!) - iphone

I want to set the marked text programmatically and since iOS5 UITextView and UITextField conform to UITextInput this should be possible but for some reason I always get the markedText to be nil. :(
What am I missing here?
This is what I've tried without success:
(While the textview is firstResponder)
1.- When the text view contains no text:
text: "", selectedRange : {0,0}, markedText: nil.
[_textView setMarkedText:#"月" selectedRange:NSMakeRange(0, 1)];
Result:
text : "", selectedRange: {0,0}, markedText: nil. (Nothing changed)
2.- When the text view contains text + some marked text:
text : "AAA", selectedRange = {0,3}, marked text at the end : "太陽"
then I do:
[_textView setMarkedText:#"地" selectedRange:NSMakeRange(0,3)];
Result :
text :"AAA", selectedRange: {0,3}, markedText: nil; (the marked text became nil)
In both cases is like setMarkedText:selectedRange: would be setting the current marked text (if some) to nil.
Any help would be highly appreciated :)
UPDATE
Since the concept of marked text seems to be unclear, here is an explanation:
In multi stage input languages (e.g. Japanese) you can input regular text (like english) or input marked text (like japanese).
Here I wrote regular text : regular text then I wrote marked text つ
and then I wrote marked text き so it was appended becoming つき.
Marked text (text in the blue box) represents a transitional or intermediate input stage because it can become into other characters/words called candidates. Candidates are shown in the big box.
This screenshot was taken when using a bluetooth keyboard in the iPad but you will get similar results when using the software keyboard when writing japanese for example.
Before writing つ the textview was:
textView.text : "regular text"
textView.selectedRange : {12,0}
textView.markedText:nil
Then I wrote つ and the text view became:
textView.text : "regular textつ"
textView.selectedRange : {13,0}
textView.markedText: "つ"
Then I wrote き and the text view became:
textView.text : "regular textつき"
textView.selectedRange : {14,0}
textView.markedText: "つき"
Which is the current state of the text view.
I want to be able to set the marked text programatically :)
Is this possible? -- According to UITextInput docs it is.

I have a conceptual problem with your code here. I may just be overlooking some small thing, but I think you just have a simple error in your programming.
1) When the text view contains no text: text: "", selectedRange : {0,0}, markedText: nil:
[_textView setMarkedText:#"月" selectedRange:NSMakeRange(0, 1)];
Result: text: "", selectedRange: {0,0}, markedText: nil.
(Nothing changed)
2) When the text view contains text + some marked text: text: "AAA", selectedRange: {0,3}, markedText at the end: "太陽" then I do:
[_textView setMarkedText:#"地" selectedRangeNSMakeRange(0,3)];
Result: text: "AAA", selectedRange: {0,3}, markedText: nil;
(the marked text became nil)
I just fixed your problem in the code that I ran in Xcode. It ran flawlessly and changed the marked text when I clicked three different buttons. When there was no marked text, the text was appended and marked.
text is the name of a UITextView:
-(IBAction)first
{
[text setMarkedText:#"test" selectedRange:NSMakeRange(0, 4)];
}
-(IBAction)second
{
[text setMarkedText:#"woo" selectedRange:NSMakeRange(0,4)];
}
Here I clicked "First"
Here I clicked "Second"
I hope this helps you and is deserving of the bounty.

Did you add the UITextField to the view before setting it's contents (and marking the text)?

Related

NSSearchField - How to select all text? (Swift/Storyboards on macOS)

It seems everything online is mostly about iOS/UI controls, not macOS/Cocoa NS controls. Anyway, How does one make an NSSearchField select all text in the field programatically? I have tried multiple methods adapted from the iOS UISearchBar implementations, but none of them compiled or worked. I just want to, for instance, press a button and have it hilight the text that is inside the NSSearchField's text field. I can't seem to find a method within it that allows this to happen.
Thank you for your help/consideration!
All editing in NSTextField is handled by NSText (which inherits from NSTextView). So, to select the text in your search field, you need to set the selected range in field's current editor. This example highlights the whole text.
Objective-C:
NSRange range = NSMakeRange(0, searchField.stringValue.length);
NSText *editor = [searchField currentEditor];
[editor setSelectedRange:range];
Swift
let range = NSRange(location: 0, length: searchField.stringValue.length)
let editor = searchField.currentEditor()
editor?.selectedRange = range

Handle paragraphs in swift

Is there a recommended way of handling paragraphs in swift? I am very new to swift so I'm not sure what the recommended solution or any solution for that matter is.
I want to be able to open a .txt file and be able to select a paragraph, selecting the paragraph needs to print the selected paragraph to a label.
I haven't got any code for this yet, other than opening and viewing the text file by doing the following:
let file = "/Users/wade/Desktop/ht.txt"
let path=URL(fileURLWithPath: file)
let text=try! String(contentsOf: path)
textView.stringValue = text
Once the .txt file is displayed I want to be able to click on a paragraph and have the paragraph display in a separate label
I am not fixed on using .txt files if there is a better format for achieving this
I'm guessing that printing to the label should be as easy as
let selectedParagraph = //however we identify the paragraph stringvalue
let thelabel = selectedParagraph.stringValue
But I need to know how to identify and get the text from the paragraph
Create a subsclass of NSTextView and use it to display the whole text. This will always select text by paragraph:
class ParagraphTextView: NSTextView {
override func selectionRange(forProposedRange proposedCharRange: NSRange,
granularity: NSSelectionGranularity) -> NSRange {
return super.selectionRange(forProposedRange: proposedCharRange,
granularity: .selectByParagraph)
}
}
Then set a delegate (NSTextViewDelegate) and track selection changes of the text view to update your secondary label with the current selection.

How can I use ValidationSupport between two textfields?

I would like to use the ValidationSupport to check the content of textfield2 against the content of textfield1. Here is what I tried to do :
validationSupport = new ValidationSupport();
validationSupport.registerValidator(textfield2, false, (Control c, String newValue)
-> ValidationResult
.fromMessageIf(textfield2,
"Should contain texfield",
Severity.WARNING,
!newValue.contains(textfield1.getText())));
validationSupport.initInitialDecoration();
Filling textfield1 first, then texfield2 is working as I expect : the warning decoration is displayed on textfield2 until the textfield1 content is not included in the texfield2 content.
But starting from same content in textfield 1 & 2, and trying to change texfield1 again (hence at this point, textfield1 content differ from textfield2 content), I was expecting the warning decoration to be displayed immediately on texfield2, which is not the case !
Indeed in order to have the validationSupport checked again, I need to update the textfield2 again. Only after the texfield2 content has been updated, then the ValidatorSupport is checked again, and the decoration is updated accordingly !
The only way I found to always get the decoration up to date is to remove the previous registerValidator and to add a listener on textfield1 textProperty to register a new validator for texfield2 each time textfield1 content is changed :
textfield.textProperty().addListener((observable, oldValue, newValue)
-> validationSupport.registerValidator(textfield2, false, (Control c, String str)
-> ValidationResult
.fromMessageIf(textfield2,
"Should contain texfield1",
Severity.WARNING,
!str.contains(textfield.getText()))));
This is working (meaning when I change textfield1, decoration on textfield 2 is updated immediately) but I feel it's not the right solution, but can't find another / better one. Is it the right way to do ? If not, what is the right way ? Any recommendation ? Thanks.

Cocoa/Swift: NSStatusBarItem's text gets trimmed when using a picture

When creating an NSStatusBar.systemStatusBar related application for MacOS, I stumbled upon a problem that seemed strange to begin with. The problem is: when using an image and a text for the NSStatusBar, the text was being clipped unless you manually specified a sufficient length, which would be hardcoded and causes problems with alternating lengths. How can this be solved?
// The -1 is supposed to mean "variable length"
let myStatusItem = NSStatusBar.systemStatusBar().statusItemWithLength(CGFloat(-1))
myStatusItem.image = NSImage(named: "customImage")
myStatusItem.title = "Some special information"
This would be the normal case where this problem will occur.
After playing around with some ridiculous variations, I realized that the problem can be fixed when using BOTH .title and .attributedTitle parameters of the NSStatusBar item.
Also make sure that you declare the .image BEFORE you declare the titles. If you want to use the .attributedTitle, define it after .title - if you want to use the plain .title, just define it after the .attributedTitle.
// The -1 is supposed to mean "variable length"
let myStatusItem = NSStatusBar.systemStatusBar().statusItemWithLength(CGFloat(-1))
myStatusItem.image = NSImage(named: "customImage")
myStatusItem.title = "Some special information"
myStatusItem.attributedTitle = NSAttributedString(string: "Some special information")

Add Placeholder to UITextField, how to set the placeholder text programmatically in swift?

I'm pulling out a phone number from a database, and when the user begins editing in the text field to change that phone number I'd like to use the number I currently have in the database as the placeholder. Since this information changes with each user, how can I set it programmatically in swift?
You need to get the phone number from your database first (convert them to String), then you set placeholder of your textField to that String, like so
textField.placeholder = phoneNumberString
Swift 3
If your textField has text, you need to first set text property to nil, then set placeholder text:
textField.text = nil
textField.placeholder = "My Placeholder Text"
Important to note for anyone else reading this, setting placeholder text in the main.storyboard seems to nullify this solution, so I had to first clear out my placeholders in the storyboard before implementing this. Once that was done #Khuong and #Himanshu's answer worked perfectly.
Apply this line of code in to View Did Load
new_Password.attributedPlaceholder =
NSAttributedString(string: " New Password", attributes: [NSForegroundColorAttributeName : UIColor.white]) // new_Password : our text feild name
Fetch your desired data from your database (Core data) and after converting it into string format... say phoneString
use this line to set this string as a placeholder text
phoneTextField.placeholder = phoneString
Objective-C code:
[usernameText setPlaceholder:#"My Placeholder Text"];
Just a note to say if you have changed your textfield's text and background colors programmatically, you can't do that with the placeholder text's colors and must set up an Attributed Placeholder instead. This is a problem if your device is in put in "dark mode" and are trying to make a non-dark mode screen by hand - you might not be able to see the placeholder!