可通过webView ObjectiveC

时间:2018-04-18 17:05:59

标签: ios objective-c uilabel uitapgesturerecognizer nsmutableattributedstring

我有UILabel I agree to the Terms and Policy。我希望分别使用条款和政策可点击。我已设法在条款和政策中添加属性,使其成为蓝色和下划线。但是如何分别使它们可点击。单击“条款”时,我希望推送到加载webView的新VC,同样适用于策略。我熟悉使用segue推送到另一个VC,但是在点击条款或政策时如何初始化流程>

被修改

#import "ViewController.h"

@interface ViewController ()
@end

@implementation ViewController
@synthesize label;
@synthesize layoutManager;
@synthesize textContainer;
@synthesize textStorage;

- (void)viewDidLoad {
    [super viewDidLoad];

    NSString *fullString = @"I agree to the Terms and Policy";
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:fullString];

    //For underline
    [attributedString addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:[fullString rangeOfString:@"Terms"]];
[attributedString addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:[fullString rangeOfString:@"Policy"]];
    //For Blue Colour
    [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:0.05 green:0.4 blue:0.65 alpha:1.0] range:[fullString rangeOfString:@"Terms"]];
    [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:0.05 green:0.4 blue:0.65 alpha:1.0] range:[fullString rangeOfString:@"Policy"]];

    // Setting attributed string to textview
    label.attributedText = attributedString;

    // Create instances of NSLayoutManager, NSTextContainer and NSTextStorage
    NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
    NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeZero];
    NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedString];

    //=====What does this part do, Do I really need it?======
    // Configure layoutManager and textStorage
    [layoutManager addTextContainer:textContainer];
    [textStorage addLayoutManager:layoutManager];

    // Configure textContainer
    textContainer.lineFragmentPadding = 0.0;
    textContainer.lineBreakMode = label.lineBreakMode;
    textContainer.maximumNumberOfLines = label.numberOfLines;
    //======================================================

    label.userInteractionEnabled = YES;
    [label addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapOnLabel:)]];
}

- (void)handleTapOnLabel:(UITapGestureRecognizer *)tapGesture
{

    CGPoint locationOfTouchInLabel = [tapGesture locationInView:tapGesture.view];
    CGSize labelSize = tapGesture.view.bounds.size;
    CGRect textBoundingBox = [self.layoutManager usedRectForTextContainer:self.textContainer];
    CGPoint textContainerOffset = CGPointMake((labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x,
                                          (labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y);
    CGPoint locationOfTouchInTextContainer =     CGPointMake(locationOfTouchInLabel.x - textContainerOffset.x,
                                                        locationOfTouchInLabel.y - textContainerOffset.y);
    NSInteger indexOfCharacter = [self.layoutManager characterIndexForPoint:locationOfTouchInTextContainer
                                                        inTextContainer:self.textContainerfractionOfDistanceBetweenInsertionPoints:nil];
    NSRange termsLinkRange = NSMakeRange(15, 5); // it's better to save the range somewhere when it was originally used for marking link in attributed string
    NSRange policyLinkRange = NSMakeRange(25, 6);

    //=========THE FOLLOWING PART IS NOT WORKING =====================
    if (NSLocationInRange(indexOfCharacter, termsLinkRange)) {

       NSLog(@"This is terms");
       [self performSegueWithIdentifier:@"Terms" sender:self];    

    }else if(NSLocationInRange(indexOfCharacter, policyLinkRange)){

       NSLog(@"This is policy");
       [self performSegueWithIdentifier:@"Policy" sender:self];
    }
 }
 //======================================================================
 @end

我让indexOfCharacter等于0

3 个答案:

答案 0 :(得分:1)

您可以使用UITextView来实现这一点,我在以前的项目中使用这种方式实现了这一点,使用此扩展来更轻松地创建这些链接

代码

UITextView扩展名.h

#import <UIKit/UIKit.h>

@interface UITextView (Link)

- (void)setTextAsLink:(NSString*)text url:(NSURL*)linkurl attributtes:(NSDictionary*)attributes;

@end

UITextView扩展名.m

#import "UITextView+Link.h"

@implementation UITextView (Link)

    - (void)setTextAsLink:(NSString*)text url:(NSURL*)linkurl attributtes:(NSDictionary*)attributes {

        NSMutableAttributedString * theString = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedText];
        NSRange theRange = [theString.mutableString rangeOfString:text];


        if(theRange.location != NSNotFound) {
            [theString addAttribute:NSLinkAttributeName value:linkurl range:theRange];
            self.attributedText = theString;
        }

        self.linkTextAttributes = attributes;
    }

    @end

使用它

#import "ViewController.h"
#import "UITextView+Link.h"

@interface ViewController () <UITextViewDelegate>
@property (weak, nonatomic) IBOutlet UITextView *textView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.textView.editable = false;
    self.textView.contentInset = UIEdgeInsetsZero;
    self.textView.textContainerInset = UIEdgeInsetsZero;
    self.textView.attributedText = [[NSAttributedString alloc] initWithString:@"I agree to the Terms and Policy" attributes:nil];
    self.textView.delegate = self;
    NSDictionary * linkAttributes = @{NSForegroundColorAttributeName:[UIColor redColor]};

    [self.textView setTextAsLink:@"Terms" url:[NSURL URLWithString:@"terms://"] attributtes:linkAttributes];
    [self.textView setTextAsLink:@"Policy" url:[NSURL URLWithString:@"policy://"] attributtes:linkAttributes];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


#pragma mark -
#pragma mark UITextViewDelegate

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView{
    return false;
}

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction {
    if([URL.absoluteString isEqualToString:@"terms://"]) {
        NSLog(@"TERMS SHOULD BE OPENED");
    }
    if([URL.absoluteString isEqualToString:@"policy://"]) {
        NSLog(@"POLICY SHOULD BE OPENED");
    }
    return false;
}

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {
    if([URL.absoluteString isEqualToString:@"terms://"]) {
        NSLog(@"TERMS SHOULD BE OPENED");
    }
    if([URL.absoluteString isEqualToString:@"policy://"]) {
        NSLog(@"POLICY SHOULD BE OPENED");
    }
    return false;
}

@end

enter image description here

答案 1 :(得分:0)

要实现此目的,您应该使用UITextView并使其可选。向textview添加属性将使链接可单击。所以你不需要添加手势。

不要忘记设置textview的这些属性:

textview.isSelectable = true
textview.isEditable = false
textview.isUserInteractionEnabled = true

同时实现UITextViewDelegate方法:

func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
    //open the link here
    if URL.absoluteString == "YOUR_TERMS_URL" {
        //open terms
    } else if URL.absoluteString == "YOUR_PRIVACY_URL" {
        //open privacy
    } 
    return false
}

答案 2 :(得分:0)

您可以向UILabel添加-> String code = "BB [FL:60 BT:10 SG:20 MK:10 | 12]" | Added variable code of type String with initial value "BB [FL:60 BT:10 SG:20 MK:10 | 12]" -> String[] mattime = code.split ("[\\]\\[\\|]"); | Modified variable mattime of type String[] with initial value [Ljava.lang.String;@2286778 | Update overwrote variable mattime -> mattime [1] | Expression value is: "FL:60 BT:10 SG:20 MK:10 " | assigned to temporary variable $32 of type String -> String[] elem = mattime [1].split (" ") | Modified variable elem of type String[] with initial value [Ljava.lang.String;@13a5fe33 | Update overwrote variable elem -> for (String e: elem) println (e); FL:60 BT:10 SG:20 MK:10 -> for (String e: elem) {println (e); String [] kv = e.trim().split (":") ; println (kv[0] + " : " + Integer.parseInt (kv[1])); } FL:60 FL : 60 BT:10 BT : 10 SG:20 SG : 20 MK:10 MK : 10 个实例。

        <!-- Facebook and Twitter integration -->
        <meta property="og:title" content=""/>
        <meta property="og:image" content=""/>
        <meta property="og:url" content=""/>
        <meta property="og:site_name" content=""/>
        <meta property="og:description" content=""/>
        <meta name="twitter:title" content="" />
        <meta name="twitter:image" content="" />
        <meta name="twitter:url" content="" />
        <meta name="twitter:card" content="" />

然后@ RB1509说

UITapGestureRecognizer

更新:

所以现在你需要检测文本上的触摸

UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapOnLabel)];
tapGestureRecognizer.numberOfTapsRequired = 1;
tapGestureRecognizer.delegate =self;
[myLabel addGestureRecognizer:tapGestureRecognizer];
myLabel.userInteractionEnabled = YES;

我同意条款和政策=条款- (void)handleTapOnLabel:(UITapGestureRecognizer *)gestureRecognizer { UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; secondVC *VC = [storyboard instantiateViewControllerWithIdentifier:@"secondVC"]; VC.GetString=@"https://www.vbgov.com/Pages/default.aspx"; [self presentViewController:VC animated:YES completion:nil]; } 和政策- (void)handleTapOnLabel:(UITapGestureRecognizer *)tapGesture { CGPoint locationOfTouchInLabel = [tapGesture locationInView:tapGesture.view]; CGSize labelSize = tapGesture.view.bounds.size; CGRect textBoundingBox = [self.layoutManager usedRectForTextContainer:self.textContainer]; CGPoint textContainerOffset = CGPointMake((labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x, (labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y); CGPoint locationOfTouchInTextContainer = CGPointMake(locationOfTouchInLabel.x - textContainerOffset.x, locationOfTouchInLabel.y - textContainerOffset.y); NSInteger indexOfCharacter = [self.layoutManager characterIndexForPoint:locationOfTouchInTextContainer inTextContainer:self.textContainer fractionOfDistanceBetweenInsertionPoints:nil]; NSRange termsLinkRange = NSMakeRange(15, 5); // it's better to save the range somewhere when it was originally used for marking link in attributed string NSRange policyLinkRange = NSMakeRange(25, 6); if (NSLocationInRange(indexOfCharacter, termsLinkRange)) { // Open an URL, or handle the tap on the text TERMS [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://stackoverflow.com/"]]; }else if(NSLocationInRange(indexOfCharacter, policyLinkRange)){ // Open an URL, or handle the tap on the text POLICY [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://stackoverflow.com/"]]; } } *相应地改变范围。