iOS: Scaling UITextView with pinching?

ぐ巨炮叔叔 提交于 2019-11-27 19:11:57

Try:

- (void)scaleTextView:(UIPinchGestureRecognizer *)pinchGestRecognizer{
     CGFloat scale = pinchGestRecognizer.scale;

    createTextView.font = [UIFont fontWithName:createTextView.font.fontName size:createTextView.font.pointSize*scale];

    [self textViewDidChange:createTextView];       
}

It basically scales the font size and then recalculates the content size using your code in textViewDidChange.

To elaborate on @Cocoanetics answer above. I implemented the gesture handling idea for attributed strings on iOS 7 but it is prohibitively slow when you have too many font changes in your string. There is also a ridiculous buffering bug in iOS 7 where Change notifications keep firing long after you've stopped pinching - reminds me of the stupid keyboard buffer in early versions of PC-DOS. Anyway, I have put the code below that got this working for me - although it has only resulted in informing me that this is a waste of time and that I need to give my users some other way of scaling their fonts.

- (void)scaleTextView:(UIPinchGestureRecognizer *)pinchGestureRecognizer
{
    CGFloat scale = 0;
    NSMutableAttributedString *string;

    switch (pinchGestureRecognizer.state) {
        case UIGestureRecognizerStateBegan:
            self.old_scale = 1.0;
            self.last_time = [NSDate date];
            break;

        case UIGestureRecognizerStateChanged:
            scale = pinchGestureRecognizer.scale - self.old_scale;

            if( [self.last_time timeIntervalSinceNow] < -0.2 )  {       //  updating 5 times a second is best I can do - faster than this and we get buffered changes going on for ages!
                self.last_time = [NSDate date];
                string = [self getScaledStringFrom:[self.textview.attributedText mutableCopy] withScale:1.0 + scale];
                if( string )    {
                    self.textview.attributedText = string;
                    self.old_scale = pinchGestureRecognizer.scale;
                }
            }
            break;

        case UIGestureRecognizerStateEnded:
        case UIGestureRecognizerStateCancelled:
        case UIGestureRecognizerStateFailed:
            break;

        default:
            break;
    }
}

- (NSMutableAttributedString*) getScaledStringFrom:(NSMutableAttributedString*)string withScale:(CGFloat)scale
{
    [string beginEditing];
    [string enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, string.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) {
        if (value) {
            UIFont *oldFont = (UIFont *)value;
            UIFont *newFont = [oldFont fontWithSize:oldFont.pointSize * scale];
            [string removeAttribute:NSFontAttributeName range:range];
            [string addAttribute:NSFontAttributeName value:newFont range:range];
        }
    }];
    [string endEditing];
    return string;
}
jayesh lathiya

First of all add UIPinchGestureRecognizer in viewDidLoad method:

UIPinchGestureRecognizer *pinchOnTextfield = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handleTextFieldFontOnAddMusicVc:)];
[self.myTextField addGestureRecognizer:pinchOnTextfield];

then put this method in your viewController to scale textField font:

- (void)handleTextFieldFontOnAddMusicVc:(UIPinchGestureRecognizer *)pinchGestRecognizer {
    if (pinchGestRecognizer.state == UIGestureRecognizerStateEnded || pinchGestRecognizer.state == UIGestureRecognizerStateChanged) {
        CGFloat currentFontSize = self.myTextField.font.pointSize;
        CGFloat newScale = currentFontSize * pinchGestRecognizer.scale;

        if (newScale < 20.0) {
            newScale = 20.0;
        }
        if (newScale > 60.0) {
            newScale = 60.0;
        }

        self.myTextField.font = [UIFont fontWithName:self.myTextField.font.fontName size:newScale];
        pinchGestRecognizer.scale = 1;

    }    
}

UITextView is a subclass of UIScrollView and as such you need to do what you do with any scroll view to enable zooming:

  • set the minimum and maximum zoom scale properties
  • set the viewForZooming via the scrollview delegate method

... that zooms the entire text view.

If you only want to zoom the text then you have to perform these steps via a pinch gesture recognizer:

  • retrieve the current attributed string
  • walk through the font ranges and replace the font attribute with a scaled one
  • replace the text in the text view with your modified version
  • probably you also need to set the text selection after setting the text

Not the best but easy solution would be:

I do not know exactly your use case, but I think it does not make sense in many cases to support in a app pinch zoom while typing text. I would just set a flag, which prevents pinch zoom while user is typing text.

If you mean by text typing, editing the text view you can end the editing at the beginning of the pinch gesture and start editing after pinch gesture did end.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!