Using KIF to click links in UITextView - ios

Is it possible to use KIF to click links in UITextViews? Using Accessibility Inspector seems to treat the UITextView as a single view and does not seem to recognize links.

It seems that links in UITextView objects need a longer press to activate than a standard tap with KIF. I solved this by writing my own test step using a category on KIFUITestActor. The code tries to find the text you want to tap inside of the UITextView and then long presses it.
- (void)tapText:(NSString *)text inTextViewWithAccessibilityIdentifier:(NSString *)identifier
{
[self runBlock:^KIFTestStepResult(NSError *__autoreleasing *error) {
UITextView *textView = nil;
UIAccessibilityElement *element = nil;
[self waitForAccessibilityElement:&element view:&textView withIdentifier:identifier tappable:YES];
KIFTestCondition([textView isKindOfClass:[UITextView class]], error, #"The accessibility element is not a UITextView");
NSRange range = [[textView.textStorage string] rangeOfString:text];
KIFTestCondition(range.length > 0, error, #"The text '%#' was not found in UITextView with accessibility identifier: %#", text, identifier);
range.length = 1;
range = [textView.layoutManager glyphRangeForCharacterRange:range actualCharacterRange:nil];
CGRect rect = [textView.layoutManager boundingRectForGlyphRange:range inTextContainer:textView.textContainer];
rect = CGRectOffset(rect, textView.textContainerInset.left, textView.textContainerInset.top);
CGPoint point = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
[textView longPressAtPoint:point duration:0.1f];
return KIFTestStepResultSuccess;
}];
}

Related

Set text(with emojis, special chars, links) in UILabel, and link should be clickable

In one of my application, there is API called and get data from server. In that there is text - which contains emojis, special characters, URLs, etc.
Not In my UITableViewCell, I have Simple UILabel and set text to label.
Till now everything is working fine.
But now I want that URLs in UILabel should be tappable, so when we click on URL and it should be open in Safari.
Note : As text is coming from server, so I don't know position of URL and there will be multiple URL as well.
What to do for that ? I have searched but didn't find solution.
I needed this kind of linked text for another project last month. I created a custom UITableViewCell with a UITextView object in the cell, subclassed to a custom UITextView subclass. I just made a quick demo project and put it up on git for you now. Feel free to use it.
github.com/fareast555/MPC_LinkedTextView
The basic secret sauce for using text links is the NSLinkAttributeName attribute in the mutable text, and telling the system to handle links.
- (void)updateTextViewWithFullText:(NSString *)fullText linkTriggerText:(NSString *)triggerText linkURLString:(NSString *)urlString
{
//Create a mutable string based on the full text
NSMutableAttributedString *mutableString = [[NSMutableAttributedString alloc]initWithString:fullText attributes:nil];
//Add the link attribute across the range of the target text
[mutableString addAttribute:NSLinkAttributeName value:urlString range:[fullText rangeOfString:triggerText]];
//Add any other font or color bling as needed
[mutableString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:18 weight:UIFontWeightMedium] range:NSMakeRange(0, [fullText length])];
//Set the mutable text to the textfield
[self setAttributedText: mutableString];
}
#pragma mark - UITextViewDelegate
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction
{
return YES;
}
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
return NO;
}
And for textviews, you'll find it easier to use auto layout if you turn off scrolling.
#pragma mark - Configure
- (void)_configureTextView
{
self.delegate = self;
[self setEditable:NO];
[self setSelectable:YES];
[self setScrollEnabled:NO];
[self setUserInteractionEnabled:YES];
[self setDataDetectorTypes:UIDataDetectorTypeLink];
self.scrollIndicatorInsets = UIEdgeInsetsZero;
}

UITextView change selectRange always crash

When user click the passage in textView, I want to change the cursor to the linebreak, but when I change selectionRange is always failed.
I know the reason, but I must change the selectedRange in func: textViewDidChangeSelection:(UITextView*)textView
How can I change the selectedRange?
here is the code
-(void)textViewDidChangeSelection:(UITextView *)textView
// paragLocations: it contain all "\n" locations
NSArray* paragLocations = [self ParagraphLocationsWithText:textView Pattern:translatePragraphLinebreak];
// location :According to user selection,The nearest "\n" location
NSUInteger nearestLocation = [self ClickParagraphEndBreakLoctionWithSelectLocation:textView.selectedRange.location withParagLocations:paragLocations];
//Then
//1. here I change the textView.selectedRange
textView.selectedRange = NSMakeRange(nearestLocation, 0);
//2. here I change the cursorPosition
CGFloat cursorPosition = [self caretRectForPosition:textView.selectedTextRange.start].origin.y;
[textView setContentOffset:CGPointMake(0, cursorPosition) animated:YES];
// but In step 1 ,It changed textView.selectedRange,So this func will do it again,and then again,until the nearestLocation became the paragLocations.lastObject.
/*
so the question is how to break this Infinite loop ?
should I change selectedRange In this func?
I want to changed the selectedRange base on User select In textview
*/
sorry about my poor english.
You can try the following code, it works for me fine.
- (void)textViewDidChangeSelection:(UITextView *)textView {
UITextRange *selectRange = [textView selectedTextRange];
NSString *selectedText = [textView textInRange:selectRange];
}

How to change text in UITextView and UITextField

I need to edit my UITextView and when I make these changes I need them to reflect that in my UITextFields. Currently i can use the code below to move whatever text i write into the first UITextField is there a simple way to move each line to a separate UITextField?
Like the image, except the 1, 2 and 3 going to a different UITextField.
-(IBAction)print:(id)sender {
NSString *texto = [[NSString alloc] initWithFormat:#"%# %#",[myTextField text],[myTextView text]];
[myTextField setText:texto];
[myTextView setText:#""];
[myTextView resignFirstResponder];
}
Really, I need to figure this out. Any help will be appreciated.
Have your view controller conform to the UITextViewDelegate protocol.
Next, set the delegate property of your text view to your view controller.
Then, implement - (void)textViewDidChange:(UITextView *)textView, along these lines:
- (void)textViewDidChange:(UITextView *)textView
{
// Set the text for your text fields.
//
// (I'm assuming your code for determining the text to put in the
// text fields works as you intend, so I'm just copying it here.)
NSLayoutManager *layoutManager = [textView layoutManager];
unsigned numberOfLines, index, numberOfGlyphs = [layoutManager numberOfGlyphs];
NSRange lineRange;
for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++)
{
(void) [layoutManager lineFragmentRectForGlyphAtIndex:index
effectiveRange:&lineRange];
index = NSMaxRange(lineRange);
NSString *lineText = [textView.text substringWithRange:lineRange];
[yourArray addObject:lineText];
}
textField1.text=yourArray[0];
textField2.text=yourArray[1];
textField3.text=yourArray[2];
textField4.text=yourArray[3];
textField5.text=yourArray[4];
textField6.text=yourArray[5];
textField7.text=yourArray[6];
}

hyperlink to section of text in uitextview

I am trying to set up a 'Frequently Asked Questions' section on a UITextView. How do I link a line of text on a UITextView so that when the user clicks on it, the UITextView scrolls to a section of text in the same view. I would also like to underline the text and change the text color to blue.
try TTTAttributedLabel
TTTAttributedLabel allows you to automatically detect links for dates, addresses, links, phone numbers, transit information, or allow you to embed your own.
label.enabledTextCheckingTypes = NSTextCheckingTypeLink; // Automatically detect links when the label text is subsequently changed
label.delegate = self; // Delegate methods are called when the user taps on a link (see `TTTAttributedLabelDelegate` protocol)
label.text = #"Fork me on GitHub! (http://github.com/mattt/TTTAttributedLabel/)"; // Repository URL will be automatically detected and linked
NSRange range = [label.text rangeOfString:#"me"];
[label addLinkToURL:[NSURL URLWithString:#"http://github.com/mattt/"] withRange:range]; // Embedding a custom link in a substring
You need to first fetch the click event of the text "Frequentry asked questions". on the click event you need to make code for scrolling.
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange
{
//Set your character range here
// if match return TRUE .
// else return FALSE.
}
On successful character range fetch scroll your textView to the questions by using this method.
CGPoint bottomOffset;
bottomOffset = CGPointMake(0,(Y value of the question));
[self.chatOutput setContentOffset:bottomOffset animated:YES];
This method will scroll the uitextview to the position of your question.
NSMutableAttributedString * str = [[NSMutableAttributedString alloc] initWithString:#"Google"];
[str addAttribute: NSLinkAttributeName value: #"http://www.google.com" range: NSMakeRange(0, str.length)];
yourTextField.attributedText = str;

iOS - appending string before and after the word

I want to add a string in the highlighted area in the textview, I mean by the highlighted area, where the blue line is located.
So once the user click on the button it adds a string where the "blue line" is located
I used stringByAppendingString but it adds the string after the word exists only
NSRange range = myTextView.selectedRange;
NSString * firstHalfString = [myTextView.text substringToIndex:range.location];
NSString * secondHalfString = [myTextView.text substringFromIndex: range.location];
myTextView.scrollEnabled = NO; // turn off scrolling
NSString * insertingString = [NSString stringWithFormat:#"your string value here"];
myTextView.text = [NSString stringWithFormat: #"%#%#%#",
firstHalfString,
insertingString,
secondHalfString];
range.location += [insertingString length];
myTextView.selectedRange = range;
myTextView.scrollEnabled = YES;
You need to use the selectedRange to find out where the text cursor is. Then use replaceCharactersInRange:withString: or insertString:atIndex: to insert the new text into the original text. Then update the text into the view.
Even though its not clear what you are trying to achieve, it seems that you want the user to start editing the textfield from the position where text starts. In that case , you can refer following:
Hint 1
Set your view controller (or some other appropriate object) as the text field's delegate and implement the textFieldDidBeginEditing: method like this:
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
UITextPosition *beginning = [textField beginningOfDocument];
[textField setSelectedTextRange:[textField textRangeFromPosition:beginning
toPosition:beginning]];
}
Note that setSelectedTextRange: is a protocol method of UITextInput (which UITextField implements), so you won't find it directly in the UITextField documentation.
Hint 2
self.selectedTextRange = [self textRangeFromPosition:newPos toPosition:newPos];
Hint 3
finding-the-cursor-position-in-a-uitextfield/

Resources