Coder Social home page Coder Social logo

krelborn / kilabel Goto Github PK

View Code? Open in Web Editor NEW
470.0 15.0 133.0 792 KB

A simple to use drop in replacement for UILabel for iOS 7 and above that highlights links such as URLs, twitter style usernames and hashtags and makes them touchable.

License: MIT License

Ruby 3.20% Objective-C 96.80%

kilabel's Introduction

KILabel

A simple to use drop in replacement for UILabel for iOS 7 and above that highlights links such as URLs, twitter style usernames and hashtags and makes them touchable.

KILabel Screenshot

How to use it in your project

KILabel doesn't have any special dependencies so just include the files from KILabel/Source in your project. Then use the KILabel class in place of UILabel.

  1. Download the latest source.
  2. Add the files KILabel.m and KILabel.h to your project.
  3. Either:-
    • Design your user interface as you would normally. In Interface Builder set the custom class for any UILabel you want to replace to KILabel. The label should honor all IB settings. OR
    • Create KILabel objects in code.

As Podspec is also provided so KILabel can be used by added the following line to your project's Podfile.

pod 'KILabel', '1.0.0'

You can also use KILabel with Swift. Just compile the files into your XCode project in the usual way but add the following line to your Objective-C Bridging Header.

#import "KILabel.h"

Things to know

  • To handle taps on links attach a block to one of the label's tap handler properties (See sample code).
  • Usernames and hashtag links are colored using the label's tint property. This can be configured through IB.
  • URLs are attributed using the NSLinkAttributeName and are displayed accordingly.
  • It should be possible to use either the label's text or attributedText properties to set the label content.
  • When using the attributedText property, KILabel will attempt to preserve the original attributes as much as possible. If you see any problems with this let me know.
  • The link highlighting and interaction can be enabled/disabled using the automaticLinkDetectionEnabled property.
  • The constructor always sets userInteractionEnabled to YES. If you subsequently set it NO you will lose the ability to interact with links even it automaticLinkDetectionEnabled is set to YES.
  • Use the linkAtPoint method to find out if there is link text at a point in the label's coordinate system. This returns nil if there is no link at the location, otherwise returns a dictionary with the following keys:
    • linkType a KILinkType value that identifies the type of link
    • range an NSRange that gives the range of the link within the label's text
    • link an NSString containing the raw text of the link
  • Use the linkDetectionTypes property to select the type of link you want touchable by combining KILinkTypeOption bitmasks.
  • If you attach attributedText with existing links attached, they will be preserved, but only touchable if URL detection is enabled. This is handy for manually cleaning up displayed URLs while preserving the original link behind the scenes.

A bit of sample code

The code snippet below shows how to setup a label with a tap handling block. A more complete example can be seen in the KILabelDemo project included in the repository.

// Create the label, you can do this in Interface Builder as well
KILabel *label = [[KILabel alloc] initWithFrame:NSRectMake(20, 64, 280, 60)];
label.text = @"Follow @krelborn or visit http://compiledcreations.com #shamelessplug";

// Attach a block to be called when the user taps a user handle
label.userHandleLinkTapHandler = ^(KILabel *label, NSString *string, NSRange range) {
  NSLog(@"User tapped %@", string);
};

// Attach a block to be called when the user taps a hashtag
label.hashtagLinkTapHandler = ^(KILabel *label, NSString *string, NSRange range) {
  NSLog(@"Hashtag tapped %@", string);
};

// Attach a block to be called when the user taps a URL
label.urlLinkTapHandler = ^(KILabel *label, NSString *string, NSRange range) {
  NSLog(@"URL tapped %@", string);
};

[self.view addSubview:label];

KILabel also works in Swift. Here's the above example again but in swift.

// Create the label, you can do this in Interface Builder as well
let label = KILabel(frame: CGRect(x: 20, y: 64, width: 280, height: 60))
label.text = "Follow @krelborn or visit http://compiledcreations.com #shamelessplug"

// Attach a block to be called when the user taps a user handle
label.userHandleLinkTapHandler = { label, handle, range in
  NSLog("User handle \(handle) tapped")
}

// Attach a block to be called when the user taps a hashtag
label.hashtagLinkTapHandler = { label, hashtag, range in
  NSLog("Hashtah \(hashtag) tapped")
}

// Attach a block to be called when the user taps a URL
label.urlLinkTapHandler = { label, url, range in
  NSLog("URL \(url) tapped")
}

view.addSubview(label)

Demo

The repository includes KILabelDemo, written in Objective-C, that shows a simple use of the label in a storyboard with examples for implementing touchable links.

The demo also demonstrates how to use a gesture recognizer with the label to implement a long press on a link, which uses the linkAtPoint method.

There's also an example using a UITableView where cells are given dynamic heights depending on the content.

License & Credits

KILabel is available under the MIT license.

KILabel was inspired by STTweetLabel (http://github.com/SebastienThiebaud) and others such as NimbusAttributedLabel (http://latest.docs.nimbuskit.info/NimbusAttributedLabel.html). If KILabel can't help you, maybe they can.

Contact

Open an issue to report bugs or request a feature.

Any otherfeedback welcome through the obvious channels.

kilabel's People

Contributors

krelborn avatar vilanovi avatar wnr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kilabel's Issues

link is not visible on ipad

Hello everyone

I am using on iphone its working fine,But when i run same code on ipad link is not visible but it is tappable.

Can't set custom font or font size.

I'm having trouble setting a custom font on my KILabel.

Here's my code:

 self.myLabel = [[KILabel alloc] init];
 self.myLabel.text = @"Some random text";
 self.myLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:12.4];
 self.myLabel.textColor = [UIColor colorWithRed:0.000 green:0.000 blue:0.000 alpha:1];
 [self.myLabel sizeToFit];

Any idea how I can set a custom font and font size?

Support more touch events

Currently you can only provide a block to handle touch up events on links. Touch down and drag events could also be useful.

Update examples to use iOS 8

Don't want to use deprecated code. Need to make sure everything works properly on iOS 8. Replace deprecated stuff in the demo app with iOS 8 equivalents. Mostly just replace UIAlertView with UIAlertController.

Crash if string contains NSLinkAttributeName

If string contains NSURL in NSLinkAttributeName then this code is incorrect
//KILabel.m:481
NSString *realURL = [text attribute:NSLinkAttributeName atIndex:matchRange.location effectiveRange:nil];
if (realURL == nil)
realURL = [plainText substringWithRange:matchRange];//crash

regex to not detect hashtag after a character not space

I am trying to scan for hashtags from NSStrings in Objective-C and I am using regex.
I made a test status on Facebook / Instagram to see what are the valid hashtags as it is where

Now KILabel.m (getRangeForHashTags line : 437)

regex = [[NSRegularExpression alloc] initWithPattern:@"(?<!\\w)#([\\w\\_]+)?" options:0 error:&error];

My Solution (It's works fine. when not space)

regex = [[NSRegularExpression alloc] initWithPattern:@"((#)([\\w\\_]+)?)" options:0 error:&error];

Thanks.

attributedText not works

Hi

I have table cell with KILabel inside it.
I try to set attributedText for this label by adding text alignment for some lines.
But it is not works.
When try to use normal Label with it it works fine.

Can you help me please???

How to use ignoredKeywords?

i want to ignore dot [.] detection from "@user.name"
i have tried
[cell.kiLable setIgnoredKeywords:[NSSet setWithObject:@"."]];
But it won't work.

Any suggestion guys?

can't tap when text is relayout

If the text relayout itself because of the gray highlight and the text append to be in a new line, linkAtPoint in touchesEnded will return an empty touchedLink

multiple tags written without spaces

I have tested this out and the label doesnt seem to detect the second (or anything after the first) tag if you do not place a space in between the words. So #hash#tag will only highlight #hash ...

Is there a way to fix this?
Thanks!

Manually mark range as URL

Is there a way to mark some part of text as URL? For example, in You can turn it on in Settings I want Settings to be a URL.

df

hi How to derect telephone number d

regex to ignore @ and # if there is no character after these special symbols

regex = [[NSRegularExpression alloc] initWithPattern:@"(?<!\w)@([\w_]+)?" options:0 error:&error];

should be changed to

regex = [[NSRegularExpression alloc] initWithPattern:@"(?<!\w)@([\w_]+)+" options:0 error:&error];

for detecting 1 or more characters afters @ instead of 0 or more characters.

The same should be done for getRangesForHashtags()

Shouldn't highlight when just '@' sign

Hi, more of an enhancement than a question.

I don't think it should be too difficult to add but I think that if there is no string attached to the '@' sign then it shouldn't be highlighted

This would help for when the '@' sign is used as part of a sentence

Thanks

Impact on performance

Hi, Krelborn,
When you use

- (void)drawTextInRect:(CGRect)rect
{
    // Don't call super implementation. Might want to uncomment this out when
    // debugging layout and rendering problems.
    // [super drawTextInRect:rect];

    // Calculate the offset of the text in the view
    NSRange glyphRange = [_layoutManager glyphRangeForTextContainer:_textContainer];
    CGPoint glyphsPosition = [self calcGlyphsPositionInView];

    // Drawing code
    [_layoutManager drawBackgroundForGlyphRange:glyphRange atPoint:glyphsPosition];
    [_layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:glyphsPosition];
}

Have U done some performance test ?
When I use KILabel in my tableview cell, it have a damage impact on performance,especially [_layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:glyphsPosition]; the tool , timer profile of Instruments shows it takes 27% of whole-time,which bring a significant delay when I scroll my tableview.
I am trying to improve it. I sincerely hope that U can do better modification.

Getting an Error for IB_DESIGNABLE

Getting the following error on Main.storyboard
'Failed to update auto layout status: Failed to load designable from path (null)'

I am using Xcode 7 on iOS8 - this error suddenly appeared who I upgraded to Xcode 7.

Any ideas?

Missing Colon

I have a link that is like https://www.site.com/java/Java.do

It displays correctly, but when I tap it it links to https//www.site.com/java/Java.do

This is the exact same link with a missing colon after the https. Any idea what could cause that and how to mend it?

indexPath in didSelectRowAtIndexPath

I have a tableview where cells display a KILabel, when I tapped a cell (not the kilabel link), I get the wrong indexpath, I get the previous indexPath selected.
If I remove the kilabel, everything works like a charm.

Autoshrink

Hello,

I'm using KILabel from a storyboard (adding normal UILabel and setting his custom class to KILabel). When I set Autoshrink property from inspector to 'Minimum Font Scale" apparently it does not work.

Here are a UILabel and KILabel configured equally:
ios simulator screen shot 22 6 2015 20 32 48

I'm not sure if it is an error on my configuration or a bug, so I've pushed a demo project to:
https://github.com/vbergae/KILabel_Autoshrink

I hope it helps.

Create Podspec and Integrate with Cocoa Pods

Hi,

It could be very useful if you integrate the repository in Cocoa Pods. I wanted to do it in my forked repository but as initially it is your code, better to do it yourself.

You must create a KILabel.podspec file in the root directory of the repository with the following content:

Pod::Spec.new do |s|

  s.name         = "KILabel"
  s.version      = "0.1.0"
  s.summary      = "UILabel with link, hashtags and user detectors"
  s.description  = "A simple to use drop in replacement for UILabel for iOS 7 that provides automatic detection of links such as URLs and Twitter styled usernames (@) and hashtags (#)."
  s.homepage     = "https://github.com/Kerlborn/KILabel"
  s.license      = { :type => 'MIT', :file => 'LICENSE' }
  s.author       = { "<#YOUR_NAME#>" => "<#YOUR EMAIL#>" }
  s.social_media_url = "<#YOUR_TWITTER_URL_LINK_OR_EQUIVALENT#>"
  s.platform     = :ios
  s.source       = { :git => "https://github.com/Kerlborn/KILabel.git", :tag => "0.1.0" }
  s.source_files = 'KILabel/Source/KILabel.{h,m}'
  s.framework  = 'UIKit'
  s.requires_arc = true

end

Remember to create a git tag for the desired version (0.1.0 in the example above) and merge with the CocoaPods/Specs repository. For more information check "how to create a pod" in http://cocoapods.org.

Thanks,

Joan

Question about touchesBegan in touchesEnded

In the touchedEnded method, there's this code:

if (touchedLink)
{
        NSRange range = [[touchedLink objectForKey:KILabelRangeKey] rangeValue];
        NSString *touchedSubstring = [touchedLink objectForKey:KILabelLinkKey];
        KILinkType linkType = (KILinkType)[[touchedLink objectForKey:KILabelLinkTypeKey] intValue];
        
        [self receivedActionForLinkType:linkType string:touchedSubstring range:range];
}
else
{
        [super touchesBegan:touches withEvent:event];
}

What's the purpose of the "else" part? It causes problems, when embedding your KILabel in a UITableViewCell. didSelectCell is given the wrong indexPath at some point when tapping around the UITableView.
I commented the "else" part out, and all seems to work fine after that.

Documentation is incorrect

The documentation description of how to handle links is incorrect. It needs updating to reflect the current implementation that was changed by a contributor.

KILinkTapHandler only working when Activate Breakpoints

I literally copied and pasted the KILabelTableViewController into my project I can see the tableview and hash tags I can also see the shadow highlighting effect on hashtage but never reaches call back until I Activate Breakpoint. Has anyone had this issue?

Auto layout

Hello, would this work with auto layouting? I noticed that all UILabel replacement projects that I found all use the initWithFrame approach, which doesn't really go along so well with auto layout when you want the label to fill a certain (at compile-time unknown) area.

Or am I missing something?

Thanks

UITableViewCells tap not getting recognised when used along with a UIGestureRecogniser

I am using KILabels in my UITableViewCells where I need to make the hashtags and usernames tappable. I also need the UITableViewCells to show options to the user either by swiping the cell to the left or by long pressing on the UITableViewCell. The thing is the KILabel is not catching the taps when used along with the swipe options or with the long press UIGestureRecogniser.

Support extendable link types

I would like to be able to add new link detector types in an object-oriented fashion rather than extending through enums.

tap handlers not responding.

I cannot seem to get the tap handlers to work. Ive tried hashtag and url link handlers. I see the link highlight when touching, but code within handler not getting called.

self.cardDescriptionLabel.userInteractionEnabled = true
self.cardDescriptionLabel.urlLinkTapHandler = { label, url, range in
    print("Test")   
}

Text bounds not exactly the same as a normal UILabel

Text bounds are not exactly the same as a normal UILabel. This means the KILabel is rendered in a rectangle that doesn't correspond with the method [@"string" boundingRectWithSize:options:attributes:context:](as UILabel does).

Create example using UITableView

  • (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
    self.isTouchMoved = NO;

    // Get the info for the touched link if there is one
    NSDictionary *touchedLink;
    CGPoint touchLocation = [[touches anyObject] locationInView:self];
    touchedLink = [self getLinkAtLocation:touchLocation];

    if (touchedLink)
    {
    self.selectedRange = [[touchedLink objectForKey:@"range"] rangeValue];
    }
    else
    {
    [super touchesBegan:touches withEvent:event];
    }
    }

this method can not come in,I think may be touch Event is can not catch,But I can not solve issue

Software rendered inline elements

I'm imagining being able to have an NSAttributedString where I can include an "element" that specifies a block that will be called to render and size that element. So, this would let me place arbitrary graphical elements in to a string (with the restriction that they play nicely with the line height and such?). I'm not sure what the "element" would be, but something you can stick in the string and forget about.

Example Use:

:-) For extra credit, support animation too, so I can have inline eyes that follow user taps.

Wrong Content Height Issue for no text

I am using KILablel in a UITableViewCell. I have set the height of the label to adjust as per the content using autolayout. Everything works fine in normal cases. However when the text is empty, the label still has a height with no content. On view debugging, it shows me the content height equivalent to 1 line of content. It makes the cells look bad since there is an empty space even though there isn't any content. If I am doing somethinng wrong or missing something please correct me.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.