URL / 전화 클릭 가능 UILabel을 만드는 방법은 무엇입니까?
내 앱에서 클릭 가능한 레이블을 만들어 Safari 웹 페이지로 연결하려고합니다. 또한 사용자가 전화 번호를 클릭해야만 전화를 걸 수 있기를 원합니까?
조언 해 주셔서 감사합니다
UITextView
속성을 사용하여 검사기에서 링크, 전화 번호 및 기타 항목에 대한 감지를 선택할 수 있습니다 .
UITextView
대신 사용하면 UILabel
텍스트를 하이퍼 링크로 변환 할 수있는 속성이 있습니다.
목표 -C :
yourTextView.editable = NO;
yourTextView.dataDetectorTypes = UIDataDetectorTypeAll;
빠른:
yourTextView.editable = false;
yourTextView.dataDetectorTypes = UIDataDetectorTypes.All;
링크가 자동으로 감지됩니다.
자세한 내용 은 설명서 를 참조하십시오.
https://github.com/mattt/TTTAttributedLabel
그것이 꼭 필요한 것입니다. 밑줄과 같은 레이블 속성을 적용하고 다른 색상을 적용 할 수도 있습니다. 클릭 가능한 URL에 대한 지침을 확인하십시오.
주로 다음과 같은 작업을 수행합니다.
NSRange range = [label.text rangeOfString:@"me"];
[label addLinkToURL:[NSURL URLWithString:@"http://github.com/mattt/"] withRange:range]; // Embedding a custom link in a substring
원하는대로 사용자 정의 UIButton 및 setText를 만들고 메소드를 추가 할 수 있습니다.
UIButton *sampleButton = [UIButton buttonWithType:UIButtonTypeCustom];
[sampleButton setFrame:CGRectMake(kLeftMargin, 10, self.view.bounds.size.width - kLeftMargin - kRightMargin, 52)];
[sampleButton setTitle:@"URL Text" forState:UIControlStateNormal];
[sampleButton setFont:[UIFont boldSystemFontOfSize:20]];
[sampleButton addTarget:self action:@selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:sampleButton];
-(void)buttonPressed:(id)sender{
// open url
}
UITextView가 아닌 UILabel에 의해 처리되도록하려면 다음과 같이 UILabel 하위 클래스를 만들 수 있습니다.
class LinkedLabel: UILabel {
fileprivate let layoutManager = NSLayoutManager()
fileprivate let textContainer = NSTextContainer(size: CGSize.zero)
fileprivate var textStorage: NSTextStorage?
override init(frame aRect:CGRect){
super.init(frame: aRect)
self.initialize()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.initialize()
}
func initialize(){
let tap = UITapGestureRecognizer(target: self, action: #selector(LinkedLabel.handleTapOnLabel))
self.isUserInteractionEnabled = true
self.addGestureRecognizer(tap)
}
override var attributedText: NSAttributedString?{
didSet{
if let _attributedText = attributedText{
self.textStorage = NSTextStorage(attributedString: _attributedText)
self.layoutManager.addTextContainer(self.textContainer)
self.textStorage?.addLayoutManager(self.layoutManager)
self.textContainer.lineFragmentPadding = 0.0;
self.textContainer.lineBreakMode = self.lineBreakMode;
self.textContainer.maximumNumberOfLines = self.numberOfLines;
}
}
}
func handleTapOnLabel(tapGesture:UITapGestureRecognizer){
let locationOfTouchInLabel = tapGesture.location(in: tapGesture.view)
let labelSize = tapGesture.view?.bounds.size
let textBoundingBox = self.layoutManager.usedRect(for: self.textContainer)
let textContainerOffset = CGPoint(x: ((labelSize?.width)! - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x, y: ((labelSize?.height)! - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y)
let locationOfTouchInTextContainer = CGPoint(x: locationOfTouchInLabel.x - textContainerOffset.x, y: locationOfTouchInLabel.y - textContainerOffset.y)
let indexOfCharacter = self.layoutManager.characterIndex(for: locationOfTouchInTextContainer, in: self.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
self.attributedText?.enumerateAttribute(NSLinkAttributeName, in: NSMakeRange(0, (self.attributedText?.length)!), options: NSAttributedString.EnumerationOptions(rawValue: UInt(0)), using:{
(attrs: Any?, range: NSRange, stop: UnsafeMutablePointer<ObjCBool>) in
if NSLocationInRange(indexOfCharacter, range){
if let _attrs = attrs{
UIApplication.shared.openURL(URL(string: _attrs as! String)!)
}
}
})
}}
이 클래스는이 답변의 코드를 재사용하여 만들어졌습니다 . 중요한 문자열을 만들려면이 답변을 확인하십시오 . 그리고 여기에서 전화 URL을 만드는 방법을 찾을 수 있습니다.
전체 레이블 텍스트가 아닌 특정 텍스트에만 파란색으로 링크를 만들기 때문에 이것을 너무 좋아했습니다. FRHyperLabel
할 것:
위의 링크 및 복사에서 다운로드
FRHyperLabel.h
,FRHyperLabel.m
프로젝트에.이미지에 표시된대로 사용자를 드래그 앤 드롭
UILabel
하고Storyboard
맞춤 클래스 이름을 정의 하여FRHyperLabel
관리자를 식별합니다.
- 스토리 보드에서 viewController.h 파일로 UILabel을 연결하십시오
@property (weak, nonatomic) IBOutlet FRHyperLabel *label;
- 이제 viewController.m 파일에 다음 코드를 추가하십시오.
`NSString * string = @ "업로드함으로써 이용 약관에 동의합니다"; NSDictionary * attributes = @ {NSFontAttributeName : [UIFont preferredFontForTextStyle : UIFontTextStyleHeadline]};
_label.attributedText = [[NSAttributedString alloc]initWithString:string attributes:attributes];
[_label setFont:[_label.font fontWithSize:13.0]];
[_label setLinkForSubstring:@"Terms of Use" withLinkHandler:^(FRHyperLabel *label, NSString *substring){
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.google.com"]];
}];`
- 그리고 그것을 실행하십시오.
UILabel 대신 UITextView를 사용하면 텍스트를 하이퍼 링크로 변환 할 수있는 속성이 있습니다.
스위프트 코드 :
yourTextView.editable = false
yourTextView.dataDetectorTypes = UIDataDetectorTypes.All
//or
yourTextView.dataDetectorTypes = UIDataDetectorTypes.PhoneNumber
//or
yourTextView.dataDetectorTypes = UIDataDetectorTypes.Link
extension UITapGestureRecognizer {
func didTapAttributedTextInLabel(label: UILabel, inRange targetRange: NSRange) -> Bool {
let layoutManager = NSLayoutManager()
let textContainer = NSTextContainer(size: CGSize.zero)
let textStorage = NSTextStorage(attributedString: label.attributedText!)
// Configure layoutManager and textStorage
layoutManager.addTextContainer(textContainer)
textStorage.addLayoutManager(layoutManager)
// Configure textContainer
textContainer.lineFragmentPadding = 0.0
textContainer.lineBreakMode = label.lineBreakMode
textContainer.maximumNumberOfLines = label.numberOfLines
textContainer.size = label.bounds.size
// main code
let locationOfTouchInLabel = self.location(in: label)
let indexOfCharacter = layoutManager.characterIndex(for: locationOfTouchInLabel, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
let indexOfCharacterRange = NSRange(location: indexOfCharacter, length: 1)
let indexOfCharacterRect = layoutManager.boundingRect(forGlyphRange: indexOfCharacterRange, in: textContainer)
let deltaOffsetCharacter = indexOfCharacterRect.origin.x + indexOfCharacterRect.size.width
if locationOfTouchInLabel.x > deltaOffsetCharacter {
return false
} else {
return NSLocationInRange(indexOfCharacter, targetRange)
}
}
}
왜 NSMutableAttributedString을 사용하지 않습니까?
let attributedString = NSMutableAttributedString(string: "Want to learn iOS? Just visit developer.apple.com!")
attributedString.addAttribute(.link, value: "https://developer.apple.com", range: NSRange(location: 30, length: 50))
myView.attributedText = attributedString
스위프트 4.2, Xcode 9.3 버전
class LinkedLabel: UILabel {
fileprivate let layoutManager = NSLayoutManager()
fileprivate let textContainer = NSTextContainer(size: CGSize.zero)
fileprivate var textStorage: NSTextStorage?
override init(frame aRect:CGRect){
super.init(frame: aRect)
self.initialize()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.initialize()
}
func initialize(){
let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTapOnLabel))
self.isUserInteractionEnabled = true
self.addGestureRecognizer(tap)
}
override var attributedText: NSAttributedString?{
didSet{
if let _attributedText = attributedText{
self.textStorage = NSTextStorage(attributedString: _attributedText)
self.layoutManager.addTextContainer(self.textContainer)
self.textStorage?.addLayoutManager(self.layoutManager)
self.textContainer.lineFragmentPadding = 0.0;
self.textContainer.lineBreakMode = self.lineBreakMode;
self.textContainer.maximumNumberOfLines = self.numberOfLines;
}
}
}
@objc func handleTapOnLabel(tapGesture:UITapGestureRecognizer){
let locationOfTouchInLabel = tapGesture.location(in: tapGesture.view)
let labelSize = tapGesture.view?.bounds.size
let textBoundingBox = self.layoutManager.usedRect(for: self.textContainer)
let textContainerOffset = CGPoint(x: ((labelSize?.width)! - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x, y: ((labelSize?.height)! - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y)
let locationOfTouchInTextContainer = CGPoint(x: locationOfTouchInLabel.x - textContainerOffset.x, y: locationOfTouchInLabel.y - textContainerOffset.y)
let indexOfCharacter = self.layoutManager.characterIndex(for: locationOfTouchInTextContainer, in: self.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
self.attributedText?.enumerateAttribute(NSAttributedStringKey.link, in: NSMakeRange(0, (self.attributedText?.length)!), options: NSAttributedString.EnumerationOptions(rawValue: UInt(0)), using:{
(attrs: Any?, range: NSRange, stop: UnsafeMutablePointer<ObjCBool>) in
if NSLocationInRange(indexOfCharacter, range){
if let _attrs = attrs{
UIApplication.shared.openURL(URL(string: _attrs as! String)!)
}
}
})
}}
UIButton을 사용한 Swift 4.0 가능한 솔루션
phoneButton = UIButton(frame: CGRect(x: view.frame.width * 0, y: view.frame.height * 0.1, width: view.frame.width * 1, height: view.frame.height * 0.05))
phoneButton.setTitle("333-333-3333", for: .normal )
phoneButton.setTitleColor(UIColor(red: 0 / 255, green: 0 / 255, blue: 238 / 255, alpha: 1.0), for: .normal)
phoneButton.addTarget(self, action: #selector(self.callPhone), for: .touchUpInside )
@objc func callPhone(){
UIApplication.shared.open(URL(string:"tel://3333333333")!, options: [:] , completionHandler: nil)
}
참고 URL : https://stackoverflow.com/questions/10681965/how-to-make-url-phone-clickable-uilabel
'IT박스' 카테고리의 다른 글
build.gradle에 maven 저장소 추가 (0) | 2020.08.03 |
---|---|
인증서를 가져온 후 Java Keytool 오류, "keytool 오류 : java.io.FileNotFoundException & 액세스 거부" (0) | 2020.08.03 |
ActiveMQ는 무엇에 사용됩니까? (0) | 2020.08.03 |
java.lang.NoClassDefFoundError : Java 메일 용 JUnit 테스트 케이스의 경우 com / sun / mail / util / MailLogger (0) | 2020.08.03 |
방법이 존재하는지 확인 (0) | 2020.08.03 |