optonaut / activelabel.swift Goto Github PK
View Code? Open in Web Editor NEWUILabel drop-in replacement supporting Hashtags (#), Mentions (@) and URLs (http://) written in Swift
License: MIT License
UILabel drop-in replacement supporting Hashtags (#), Mentions (@) and URLs (http://) written in Swift
License: MIT License
able to set numberOfLines = 4 once the text over 4 lines it will show ...More? And, ...More able to let user to press it.
I am trying to make the label autoshrink by setting in the interface builder: Autoshrink: Minimum Font Size 9, but it has no effect. I want to make the label gets smaller to make the whole string fit inside the UILabel´s frame. Any fixes for this?
Can we add cocoapods support? I can make a pull request with cocoapods support.
Sorry, please ignore this issue
Will this ever be supported via Objective-C?
Thank you develop the library, but does not support Chinese, looked at them, use regular expressions, no modification is successful, I hope you can support the Chinese as soon as possible, thank you.
I wish to use other regular expressions。regular expression:Hashtags use (?<!\w)#([\w_]+)?# Mentions use (?<!\w)@([\w_]+)?
Thank you guys! It's the best what I've seen!
So I'm not sure but it seems like handles do not work in 0.3.7. I downloaded and compiled source code folder 0.3.7 and 0.3.6. In 0.3.6 handleMentionTap, handleHashtagTap, handleURLTap working as expected. In 0.3.7 they don't work.
I'd like to know the tap location (or rect of tapped hashtag) so that I can present a popover (on iPad) at the correct location.
activeLabel.text = "This is a @test with various @mentions and #hashtags and http://urls.com"
activeLabel.handleHashtagTap { (hashtag) in
let alert = UIAlertController(title: "open #" + hashtag, message: "", preferredStyle: .ActionSheet)
alert.addAction(UIAlertAction(title: "Twitter", style: .Default, handler: nil))
alert.addAction(UIAlertAction(title: "Instagram", style: .Default, handler: nil))
let popover = alert.popoverPresentationController
if let popover = popover {
popover.sourceView = self.activeLabel
popover.sourceRect = self.activeLabel.bounds
popover.permittedArrowDirections = .Any
}
self.presentViewController(alert, animated: true, completion: nil)
}
You can see in the above that I'm using the ActiveLabel as the source view, so the popover's arrow comes from the edge of it, but it would be neat to know where the actual word is, so the arrow can point to it.
The dot
+user mention
(.@poolqf) is a common pattern in twitter for example.
Maybe we could add this exception in the regex.
@schickling could you help me on that? I'm not very good with regex
Thanks
Hey just ran my app with the latest Cocoapod (0.4.1) and it crashed cause the URLEnabled and hashtagEnabled properties are missing.
Here's an image of the log:
(https://cloud.githubusercontent.com/assets/4806770/13538667/c7e140e2-e200-11e5-8ec8-9537483de568.png)
How to fix, When i set ActiveLabel to UILabel class in storyboard , xCode 8 Storyboard failed to render auto layout
Hi,
I am using ActiveLabel in my app, and there's a case where I need the text to be horizontal and vertical aligned. But setting the textAlignment
property does not change anything.
I added a line on the addLineBreak(attrString:)
method expecting it to center the text as expected, but the result is the following:
Correct center alignment, but incorrect vertical one.
/// add line break mode
private func addLineBreak(attrString: NSAttributedString) -> NSMutableAttributedString {
let mutAttrString = NSMutableAttributedString(attributedString: attrString)
var range = NSRange(location: 0, length: 0)
var attributes = mutAttrString.attributesAtIndex(0, effectiveRange: &range)
let paragraphStyle = attributes[NSParagraphStyleAttributeName] as? NSMutableParagraphStyle ?? NSMutableParagraphStyle()
paragraphStyle.lineBreakMode = NSLineBreakMode.ByWordWrapping
paragraphStyle.alignment = textAlignment //ADDED THIS
if let lineSpacing = lineSpacing {
paragraphStyle.lineSpacing = CGFloat(lineSpacing)
}
attributes[NSParagraphStyleAttributeName] = paragraphStyle
mutAttrString.setAttributes(attributes, range: range)
return mutAttrString
}
A solution to accomplish the center alignment would be to add a didSet
on it, as on the other variables.
As for the vertical alignment, I tried a lot of things to accomplish it, but without luck, so I have no clues...
PS. I have an extension of ActiveLabel that uses a delegate instead of having to set block for each Label you create to handle user touches. Do you want me to create a PR with it?
1st off, this is awesome. Thank you for the work and effort!
I have ActiveLabel in a UITableViewCell:
let label = ActiveLabel()
var urlToLoad: String = ""
lazy var bodyLabel: UILabel = {
let label = ActiveLabel()
label.URLColor = UIColor(red: 85.0/255, green: 238.0/255, blue: 151.0/255, alpha: 1)
label.URLSelectedColor = UIColor(red: 82.0/255, green: 190.0/255, blue: 41.0/255, alpha: 1)
label.font = UIFont.preferredFontForTextStyle(UIFontTextStyleBody)
label.numberOfLines = 0
label.lineSpacing = 4
return label
}()
It works fine and picks up the URL's
If I put the .handleURLTap { self.alert("URL", message: $0.absoluteString) } code in the UITableViewCell then the code works and is executed but I can't segue from with UITableViewCell.
If I put the code into:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = ... // code removed
cell.label.handleURLTap({ NSURL in print("Success. Loading \(NSURL)")})
..
}
How do I call the URL thats inside the UITableViewCell from the UIViewController so I can load that URL?
I'm using ActiveLabel as the Custom Class for my post’s content labels in the Storyboard; however, I believe it is interfering with Autolayout. For some reason the post’s content gets cut off (screenshot attached).
I guess it’s hard to know without seeing my code - but do you have a clue why this might be?
Not sure why but when I add ActiveLabel to my storyboard and IBoutlets, it causes my tableviews to stutter and jump.
I've seen this idea in a Twitter java implementation.
Note this checking might be optional. If developer knows for sure the texts will contain one of the elements, then this is actually slowing execution (but i think its a very very rare scenario). Also, i don't know the real impact of this in Swift since i havn't tested yet, but I guess this should improve since character search should be way faster than regex eval.
Source of the idea & good resource for regexs and matching:
https://github.com/twitter/twitter-text/blob/810c05271c6d295211760139f4ab04749495b38a/java/src/com/twitter/Extractor.java
Hi,
ActiveLabel.swift is very useful and thank you.
I have a suggestion. Phone Number is important element is phone system. it looks like URL.
How about support detect Phone Number?
Events and scroll conflict
I came to ask questions of, UILabel added to the UITableViewCell, slide UILabel not scroll.
Know where the problems userInteractionEnabled = true, how do you solve it?
Would it be possible to expand the search for usernames to include ones that have periods in them, such as my name "@alex.figueroa"? It is currently being highlighted only until the period. (It seems Github does this with their markdown too 😅)
let string = "Test string with new line \n#hashtag"
- don't work.
The API doesn't work so well when I'm using TableView or CollectionView... sometimes the label doesn't have text and the cell is getting the old value for this label... duplicating my text and showing wrong.
To fix that... I've had to improve some part of the code... see my solution:
override public var text: String? {
didSet {
if text != nil && text != "" {
updateTextStorage()
} else {
self.textStorage.setAttributedString(NSAttributedString())
}
}
}
I hope help someone else and/or improve your code... Great API that you make... Congrats
The text is always stick to the top. Even though the height is increased.
I noticed in my app that the word "picture" is detected as a URL. After looking into it, I noticed that any phrase starting with "www" or "pic" will get detected as a URL, even though they are not valid URLs. Looking at the history, we used to use NSDataDetector but switched to a regex. Is there a compelling reason not to use NSDataDetector for this? The only test that fails using NSDataDetector is that "google.com" gets detected as a URL when the test does not want it to be (I would actually prefer it to be). Right now I am running with my fork that uses NSDataDetector until this can be resolved.
Just a pedant issue!
While playing and trying to improve the regexs i found a bad test design. Your test code is written to succeed, but does not handle failure well. Problem is caused because you don't prevent "inner" assertion execution when "outer" asserts fails and this leads to a currentElementString/currentElementType .first!
un-wrapp crash.
E.g, this test of comma-mention test cause an exception instead of an assertion failure.
label.text = ",@userhandle"
XCTAssertEqual(activeElements.count, 1) // This evaluates to false, which is OK
XCTAssertEqual(currentElementString, "userhandle") // But then currentElementString will fail becouse activeElements.first!
XCTAssertEqual(currentElementType, ActiveType.Mention)
This would be the good way; test fails without crashing:
label.text = ",@userhandle"
XCTAssertEqual(activeElements.count, 1)
if(activeElements.count>0) {
XCTAssertEqual(currentElementString, "userhandle")
XCTAssertEqual(currentElementType, ActiveType.Mention)
}
UILabel as a Active Label does not center as a normal UILabel:
Image in Storyboard: http://i.stack.imgur.com/vVYLX.png
Image in runtime: http://i.stack.imgur.com/A0mLQ.png
Even if my settings is set to the original, it does not go centre/in the middle. If i remove the ActiveLabel from my UILabel, it works perfect.
When scrolling on a table view and a tap is done on a url (for example), the handleTap block is triggered (opening a web browser in my case) thus troubling the experience of the users when they only want to scroll. Could it be possible to trigger the block exclusively on touch up? (or if not, add an option to it?)
Great plug-in by the way!
I'm thinking to port the ActiveLabel into objective-c in case if anyone needs it without bridging objc/swift. Do you guys its worth to do this? I'd like to hear any advices!
Hashtags détection don't works with accented words.
"Voilà" for instance.
Hey, I'm setting up my label in a UICollectionViewCell subclass where I calculate the label height beforehand, but I'm seeing clipping when I switch from UILabel
to ActiveLabel
. Here's my code snippet. (I also see the same results when I use sizeThatFits to calculate the height)
let attributedComment = NSMutableAttributedString(string: comment, attributes: [NSFontAttributeName : PostContentView.commentFont, NSParagraphStyleAttributeName : Utility.paragraphStyle])
let height = attributedComment.heightWithConstrainedWidth(frame.size.width)
let commentLabel = ActiveLabel(frame: CGRect(x: 0, y: 0, width: CGRectGetWidth(frame), height: height))
commentLabel.numberOfLines = 0
commentLabel.attributedText = attributedComment
addSubview(commentLabel)
//NSAttributedString Extension
extension NSAttributedString {
func heightWithConstrainedWidth(width: CGFloat) -> CGFloat {
let constraintRect = CGSize(width: width, height: CGFloat.max)
let boundingBox = self.boundingRectWithSize(constraintRect, options: NSStringDrawingOptions.UsesLineFragmentOrigin, context: nil)
return ceil(boundingBox.height)
}
}
Below are two images using ActiveLabel
and UILabel
, respectively.
Is there a gotcha that I'm missing here? (the paragraph style just provides a lineSpacing
value of 6 btw)
I'm interested in making the Mention, Hashtag, and URL elements accessible. We need this for our automated test suite, which relies on accessibility labels. But it's also just a good thing to provide for people who need it.
I'm not 100% sure how to do it, but I'll try to copy what TTTAttributedLabel is doing.
Is there a way to handle all other taps on the label that don't match a specific active element, without breaking the active element detection?
This was mentioned in a another issue but my problem is specific to font.
When I use a custom font, PTSans, the text is cut off at the end.
this is what it should look like:
And this is what it looks with with ActiveLabel
Notice the text and time stamp at the end is missing
This is a label inside a tableview cell using Automatic dimensions for the height. the cell height changes based on the size of the label.
Hello,
I just wanted to mention that numberOfLines and truncation does not seem to be supported at all. I took a look at the code, and I'm not even sure how it should be done when using NSLayoutManager and NSTextContainer, etc.
Was wondering if a maintainer might be able to help include support for this? I think it's a pretty important feature to be missing, and this is not really a drop-in replacement for UILabel until it works.
Update the below method
private func didTapStringURL(var stringURL: String) {
if !(stringURL.containsIgnoreCase("http")) {
stringURL = "http://" + stringURL
}
guard let urlHandler = urlTapHandler, let url = NSURL(string: stringURL) else {
delegate?.didSelectText(stringURL, type: .URL)
return
}
urlHandler(url)
}
This is what the console returns me:
Terminating app due to uncaught exception 'NSRangeException', reason: 'NSMutableRLEArray replaceObjectsInRange:withObject:length:: Out of bounds'
line 225 ActiveLabel.swift inside the foreach loop:
mutAttrString.setAttributes(attributes, range: element.range)
Hi Johannes, thanks for ActiveLabel - nice work!
I notice that when using ActiveLabel in a CollectionView and scrolling up or down, I sometimes get the following error:
*** Terminating app due to uncaught exception 'NSRangeException', reason: 'NSMutableRLEArray objectAtIndex:effectiveRange:: Out of bounds'
This has also been documented in another UILabel github lib (Obj-C), here:
SebastianThiebaud/STTweetLabel#55
The bug is hard to reproduce, but it has happened multiple times. It doesn't appear to be associated with the speed of scrolling or anything else I can reproduce, but as I mentioned, it has happened multiple times now, and it does seem related to ActiveLabel. Sorry I can't be of more help.
Hi,
I successfully modified the detection String for my needs to match @userName:userId;
Where would I best modify the lib to cutoff :userId;
during rendering, but keep the original object intact? Optionally also just cutting down to username would be fine ^^
I'm having issues getting this working with UIScrollViews. UIScrollView doesn't seem to allow for interaction with the linking.
We really need Objective-C here as others have abandoned their projects
Handle functions are not working until scrolling the tableview. While scrolling handle functions are working for a moment. It's hard to describe but, cell is on Storyboard. It has single UILabel and constraints, using system-regular font and it's multiline.
Do you know anything about this issue?
By the way, it is working on clean UITableView. Unfortunately it is not possible to start making the tableview from the beginning.
Than you in advance.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.