4

I have found an issue with UITextField. I have created a subclass of uitexfield that allows the user to click on the text to start editing and then rotate and resize the text.

If you resize the textfield by making the height larger the centered text moves to the right even though the width of the textfield does not increase. I have investigated this and found that uitextfield has an internval view of the type UIFieldEditor which in turn has a _UIFieldEditorContentView view. UIFieldEditor seems to be a subclass of UIScrollView and the contentsize of this scrollview becomes much larger than the size of uitextview. When the textview increases it's height the scrollviews contentsize width increases. I guess this might be an internal autolayout issue.

I have added a demo project here that demonstrates the issue. CLick on the text to start edit, then drag the resize icon so that the height increases and you will see the issue.

https://github.com/permagnus/UITextField-Resize-Issue-Demo

Screenhots from revealapp:

Any ideas on how to fix this issue?

1 Answer 1

4

I found two ways to fix the issue:

The problems lies within the underlying scrollview. One way is to find the scrollview and se how much offseted it is and compensate for the wrong offset:

- (CGRect)editingRectForBounds:(CGRect)bounds { CGRect editRect = [super editingRectForBounds:bounds]; UIScrollView *scrollView = [self findScrollViewFromView:self]; if(scrollView) { float diff = (self.bounds.size.width - scrollView.contentSize.width)/2; return CGRectInset(editRect, diff, 0); } return editRect; } - (UIScrollView *)findScrollViewFromView:(UIView *)view { if([view isKindOfClass:[UIScrollView class]]) { return (UIScrollView *) view; } for(UIView *v in view.subviews) { UIScrollView *scrollView = [self findScrollViewFromView:v]; if(scrollView) { return scrollView; } } return nil; } 

I also contacted Apple Support to get their point of the problem. They confirmed that this probably is a bug and I have submitted it as one. Their solution is the following:

Field editor is only activated for current editing session, so you can end the editing session of the text field (by calling resignFirstResponder) before resizing it (in touchesBegan... ?). In your scenario, I guess keeping the editing session might not be necessary.

If you really need to keep the editing session, one solution (ugly) I can see is to reset the text and make sure the cursor is at the beginning of document:

self.text = [self.text copy]; UITextPosition *beginningOfDocument = [self positionFromPosition:self.beginningOfDocument offset:0]; self.selectedTextRange = [self textRangeFromPosition:self.beginningOfDocument toPosition:beginningOfDocument]; 

Both of these solutions are shitty hacks and are not recommended so you use these at your own risk :)

Sign up to request clarification or add additional context in comments.

1 Comment

thank you for finding these workaround. Using Apple-suggested. Calling after any becomeFirstResponder something like this private func resetTextField(textField: UITextField) { let text = textField.text textField.text = "" textField.text = text }

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.