Ich möchte in meiner App ein anklickbares Etikett erstellen, das mich zu einer Safari-Webseite führt. Ich möchte auch, dass der Benutzer die Nummern nur durch Klicken anrufen kann.
Vielen Dank für Ihre Ratschläge
Ich möchte in meiner App ein anklickbares Etikett erstellen, das mich zu einer Safari-Webseite führt. Ich möchte auch, dass der Benutzer die Nummern nur durch Klicken anrufen kann.
Vielen Dank für Ihre Ratschläge
Antworten:
Sie können UITextView
im Inspektor a verwenden und Erkennung für Links, Telefonnummern und andere Dinge auswählen.
Verwenden Sie UITextView
anstelle von UILabel
und es hat eine Eigenschaft, um Ihren Text in einen Hyperlink zu konvertieren.
yourTextView.editable = NO;
yourTextView.dataDetectorTypes = UIDataDetectorTypeAll;
yourTextView.editable = false;
yourTextView.dataDetectorTypes = UIDataDetectorTypes.All;
Dadurch werden Links automatisch erkannt.
Einzelheiten finden Sie in der Dokumentation .
https://github.com/mattt/TTTAttributedLabel
Das ist definitiv was du brauchst. Sie können auch Attribute für Ihr Etikett anwenden, z. B. Unterstreichung, und verschiedene Farben darauf anwenden. Überprüfen Sie einfach die Anweisungen für anklickbare URLs.
Hauptsächlich machen Sie so etwas wie das Folgende:
NSRange range = [label.text rangeOfString:@"me"];
[label addLinkToURL:[NSURL URLWithString:@"http://github.com/mattt/"] withRange:range]; // Embedding a custom link in a substring
Sie können einen benutzerdefinierten UIButton und setText erstellen, was immer Sie möchten, und damit eine Methode hinzufügen.
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
}
Wenn Sie möchten, dass dies von UILabel und nicht von UITextView behandelt wird, können Sie eine UILabel-Unterklasse wie die folgende erstellen:
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)!)
}
}
})
}}
Diese Klasse wurde erstellt, indem Code aus dieser Antwort wiederverwendet wurde . Überprüfen Sie diese Antwort , um zugeordnete Zeichenfolgen zu erstellen . Und hier finden Sie, wie Sie Telefon-URLs erstellen.
Verwenden Sie dies, es hat mir so gut gefallen, da eine Verknüpfung mit blauer Farbe zu einem bestimmten Text nur nicht auf dem gesamten Etikettentext erstellt wird: FRHyperLabel
Machen:
Download Link oben und Kopie FRHyperLabel.h
, FRHyperLabel.m
zu Ihrem Projekt.
Ziehen Sie die Dropdown-Liste UILabel
in Ihren Storyboard
und definieren Sie den benutzerdefinierten Klassennamen, FRHyperLabel
um den Inspektor wie in der Abbildung gezeigt zu identifizieren.
@property (weak, nonatomic) IBOutlet FRHyperLabel *label;
`NSString * string = @" Durch das Hochladen stimme ich den Nutzungsbedingungen zu "; NSDictionary * Attribute = @ {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"]];
}];`
Verwenden Sie UITextView anstelle von UILabel und es verfügt über eine Eigenschaft, mit der Sie Ihren Text in einen Hyperlink konvertieren können
SWIFT-Code:
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)
}
}
}
Warum nicht einfach NSMutableAttributedString verwenden ?
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
Weitere Details finden Sie hier
Swift 4.2, Xcode 9.3 Version
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)!)
}
}
})
}}
Swift 4.0 mögliche Lösung mit UIButton
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)
}