How to make a string clickable using Twui? - objective-c

I have a project base on twitter's twui framework.I'm trying to made a string clickable just like
[s addAttribute:NSLinkAttributeName value:#"http://apple.com/" range:attrRange];
in NSMutableAttributedString, or performing a selector when clicked.
TUITextRender can draw a NSAttributedString, but "NSLinkAttributeName" doesn't work.
I can't find any method or delegate to solve this in TUITextView too.
How can I done this with twui?

After read source code, I figured it out.
Store ranges in a array of ABActiveRange (Which contains in twui) subclass.
Implement TUITextRendererDelegate in your UIViewController.
In the activeRangesForTextRenderer: delegate method, return the array you made in step 1.
Enjoy ~

Related

Where to define NSArray and where to define Button action?

I have made an array of text strings and want to pull these out an into a label by EITHER swiping of pressing a button. So i have two different functions/methods, the button and the swipe method.
Where and how do I define the array so that these methods can refer to it? Should it be a 'extern NSArray' ?
I have uploaded the image of full code externally http://s1.postimg.org/b2e3m4v67/Sk_rmbillede_2014_05_11_kl_15_48_28.png
Not sure though if that's a violation of some rules here(?)
You want the quote to change on swipe/button press.
In your button press/swipe methods you're setting the text property of the VC's label property to something called Quoteselected. And it looks like Quoteselected is a random element of the array Quotes - or at least maybe it is, since that random number could be 6-10, and you don't have any objects in the Quotes array at those indices - so if those numbers are ever generated by the random function, your program will crash due to an index out of bounds error.
What you probably want to do is generate a new random number on each user interaction and then at that point change the value of Quoteselected to be the object at that index of the array. And then assign that to the label's text property.
As far as defining the Array - I wouldn't have done it the way you did. What you've got there is an "ivar", an instance variable. On iOS, those are typically properties. And since it's a "private" array that outside classes won't need to know about, I'd declare it as a part of the class extension.
So,
#interface BOViewController()
#property NSArray *quotes;
#end
Also note my capitalization changes, that's better style.
So now you've got an array property declared, but there's no data in it. It depends on how you created your View Controller instance. Assuming you did it in a storyboard, it would go in awakeFromNib: or viewDidLoad: (if you instantiated the VC automatically, you might put it in the initWithNibName: method).
- (void)viewDidLoad {
[super viewDidLoad];
self.quotes = #[#"Test", #"Number 3"...];
Then when you want to reference the array in other parts of the class:
self.label.text = self.quotes[0];
Note that your existing code should work, it's just not typical Cocoa coding style.

How to insert a NSButton into a NSTextView? (inline)

I have a NSTextView and a custom NSButton. What I want to do is to insert that button (60x16 in size) to the end of the NSTextView.
How can I do something like that? I've been trying to search around on how to do this but I'm not getting anywhere.
Where should I begin? Thanks
I believe this question is pretty similar to yours:
Buttons inside an NSTextView / NSTextStorage
Quote from the question:
how do I get an NSButton to appear inside the text and react to
clicks?
Note that the issue is not fully solved there, but it seems the OP got a good head start. Hopefully you can take some clues from the discussion.
Here is one answer:
NSTextAttachment holds the contents of an attachment; it is the value
of the NSAttachmentAttributeName attribute for the
NSAttachmentCharacter in the attributed string. The contents are
usually given by an NSFileWrapper, but this is not required; you can
create an empty NSTextAttachment with a nil file wrapper.
NSTextAttachmentCell handles display and user interaction for the
attachment. By default an NSTextAttachment will create an
NSTextAttachmentCell to display itself, depending on the contents of
the attachment; in the generic case this will just be an image cell
displaying an icon.
If you wish, however, you can supply a custom NSTextAttachmentCell for
your attachment. It need not be an member of the class
NSTextAttachmentCell; it only needs to conform to the
NSTextAttachmentCell protocol. Actually, even that is not strictly
necessary; it only needs to implement a few of the basic methods for
sizing and drawing. Most cells already do this.
You will, however, need to deal with mouse events yourself. The
methods you'll probably want to implement would be
wantsToTrackMouseForEvent:inRect:ofView:atCharacterIndex: and
trackMouse:inRect:ofView:atCharacterIndex:. The character index here
should let you determine which portion of the text is relevant.

How do we implement selectionRectsForRange: from UITextInput Protocol?

How do we implement selectionRectsForRange: from UITextInput Protocol ?
Has anybody figured out this one?
Is it just very dependent upon specific use-case needs? Or is there something in the frameworks that will call this method?
To silence the compiler it is of course appropriate to stub out the method, but will returning nil or an empty NSArray cause any harm?
According to session 220 at WWDC12 this method was added to support subclassing of UITextView where the implementation renders its own text. Sadly their sample code from that session isn't available, would love to peek at it to see if I've missed anything in my implementation.
It's fairly similar to how you'd implement -firstRectForRange: except you'd return all rects which covers the current selection.
Furthermore you'd have to subclass UITextSelectionRect (it's an abstract class like UITextPosition/UITextRange) which you'd return an array of from this method. Make sure to calculate the containsStart and containsEnd properties correctly and only return YES for one of each once across all the selection rects you return. These properties are used by UITextView to decide on where to place the selection resize "paddles".
Returning an empty array (or nil I suppose) would indicate that UITextView shouldn't draw any selection rects for the current selection.

Right way to create a customizable uiview

this question is about "style", because i think this is a very common problem and i'm looking for an elegant solution.
I have created some "advanced" UIView and i try to make them very customizable.
Usually i create the UIView structure inside a custom init method, but i need to know the value of all customizable parameter inside init method so sometimes i need a very long init method like:
initWithFrame:color:font:verticalspace:verylonglist:
I tried to use delegate design pattern but i need also to pass delegate inside init method.
My actual best solution is to leave empty the init method and move everything about layout inside a "configure" method. everytime i chance a property like background color or font i will call this method and i will rebuild the view.
I think there is a best way to solve this problem...
I'd be curious to see the code of UITableView Class, because with that class you can pass a delegate outside init method.
Check out something like a UIButton or UILabel. They both have tons of configurable aspects, however to simply create an instance of one of those objects, they need very little information.
In general, provide init methods that allow the consumer of your class to specify the least amount of information for the class to work.
If you do want to give the consumer a way to initialize the class with a bunch of values, consider using some sort of initWithDictionary: method that takes an NSDictionary of parameters. This keeps your method names short and allows the user to customize an arbitrary number of settings for your class.
You could also consider providing a way for the consumer to request an instance with some standard set of values. UITableViewCell, for example, has an initWithStyle:reuseIdentifier: method. The important part is the style - UITableViewCell provides several default styles like UITableViewCellStyleDefault and UITableViewCellStyleSubtitle.
I don't know if it is the standard/best practices way but I use a dictionary in cases like this and pass that to an initWithDictionaryinitializer. Would be possible too to create a class method that returns a 'default settings' type dictionary which can then be customized (and delegate set), so that not every param needs to be specified whenever the class is used.

Objective C/iOS: Handling a selector call when a row is selected in a tableView.

I have a tableViewController with a bunch of different options and I'm trying to add a selector call when one of those rows is selected.
The way I have it setup right now is that my TableViewController's child class has a subclass inside it that has a field 'selector' and I've been messing around with trying to invoke the selector there. However, this doesn't give me access to the object that actually implements the method the selector represents.
What is the right way to add a selector to an object? This object isn't going to be a button, and in the end the selector needs to be triggered on a didSelectRowAtIndexPath: call.
Any suggestions are welcome.
Cheers.
The way I solved this was by subclassing the cells, adding a delegate and selector property. Which I then again accessed in didSelectRowAtIndexPath. I realize that this might not be best practise though, but it works.
I think a good design for this problem would be to enumerate ALL the selectors you would be interested in calling (this of course is a finite number of selectors, as they are all required to exist explicitly), add this as a property to the cells (this would mean that you need to subclass UITableViewCell, of course) and write a switch-case in the didSelectRowAtIndexPath: method.