Reputation: 528
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:
Incorrect size of underlying view in scrollview: https://github.com/permagnus/UITextField-Resize-Issue-Demo/blob/master/Screenshots/screenshot-showing-incorrect-size.png
The actuall size of the uitextfield: https://github.com/permagnus/UITextField-Resize-Issue-Demo/blob/master/Screenshots/screenshot-showing-textfield-size.png
Any ideas on how to fix this issue?
Upvotes: 4
Views: 1367
Reputation: 528
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 :)
Upvotes: 4