【问题标题】:iOS: Scaling UITextView with pinching?iOS:用捏合缩放 UITextView?
【发布时间】:2012-12-02 12:53:47
【问题描述】:

我有兴趣创建UITextView,它会在键入文本时动态扩展,并在用户捏住屏幕时进行缩放(在 TinyPost 中可以找到类似的行为)。

当您只需键入(不捏)时,textView 会很好地展开。当你只捏(不打字)时可以正常工作,但是当你捏然后打字时,里面的文字会被剪掉。

这是我的代码:

UIPinchGestureRecognizer *pinchGestRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scaleTextView:)];
        pinchGestRecognizer.delegate = self;
        [bgFrameImageView addGestureRecognizer:pinchGestRecognizer];

    - (void)scaleTextView:(UIPinchGestureRecognizer *)pinchGestRecognizer{
        createTextView.transform = CGAffineTransformScale(createTextView.transform, pinchGestRecognizer.scale, pinchGestRecognizer.scale);

        pinchGestRecognizer.scale = 1;        
    }

    - (void)textViewDidChange:(UITextView *)textView{

        CGSize textSize = textView.contentSize;

        textView.frame = CGRectMake(CGRectGetMinX(textView.frame), CGRectGetMinY(textView.frame), textSize.width, textSize.height); //update the size of the textView  
    }

你怎么看?

【问题讨论】:

  • 你为什么不把它包装成一个UIScrollView 并从viewForZoomingInScrollView: 方法返回文本视图?

标签: iphone ios uitextview uigesturerecognizer uipinchgesturerecognizer


【解决方案1】:

试试:

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

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

    [self textViewDidChange:createTextView];       
}

它基本上会缩放字体大小,然后使用您在 textViewDidChange 中的代码重新计算内容大小。

【讨论】:

  • 我建议你解释每一行的作用
  • 嗨@k20,我有同样的问题,我使用 textFiled 你能给我一些解决方案吗...谢谢..
  • 如果您想在不更改字体属性的情况下缩放 UITextView,请在此处查看我的答案:stackoverflow.com/questions/5927223/…
【解决方案2】:

详细说明上面的@Cocoanetics 答案。我在 iOS 7 上实现了属性字符串的手势处理想法,但是当字符串中的字体更改过多时,它的速度非常慢。 iOS 7 中还有一个可笑的缓冲错误,在您停止捏合后,更改通知会持续触发很长时间 - 让我想起了早期版本的 PC-DOS 中愚蠢的键盘缓冲区。无论如何,我已经将代码放在下面,它可以为我工作 - 尽管它只会告诉我这是浪费时间,我需要为我的用户提供一些其他方式来缩放他们的字体。

- (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;
}

【讨论】:

  • 嗨阿默金。对此代码有任何改进,还是您真的放弃了它?感谢您的回复。
  • @Winston - 是的,放弃了字体缩放,现在只提供预设大小供用户选择。有点蹩脚,但我在框架的限制内工作。以后可能会再试一次,看看底层代码是否有所改进。
  • 就我而言,它工作得非常好,因为我没有像你那样多的字体。我现在唯一的问题是限制最大和最小字体大小以停止捏合手势,因此文本不会变得太大或太小,有时甚至会消失。有什么建议么?谢谢。
  • @Winston - 可能在 getScaledStringFrom 中:只是做一个初步的 enumerateAttribute: 调用检查所有字体大小乘以最大和最小大小的比例 - 如果在范围内,则执行 enumerateAttribute: 上面的调用。
  • 您的建议非常有效 :-) 非常感谢您的帮助!
【解决方案3】:

首先在viewDidLoad方法中添加UIPinchGestureRecognizer

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

然后将此方法放入您的viewController 以缩放textField 字体:

- (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 时,那时原始 textview 格式不应更改。但它会用简单的文本改变粗体和斜体文本
  • 就我而言,这是比所选答案更好的解决方案 :) 谢谢!
【解决方案4】:

UITextView 是 UIScrollView 的子类,因此您需要对任何滚动视图执行您所做的操作以启用缩放:

  • 设置最小和最大缩放比例属性
  • 通过滚动视图委托方法设置 viewForZooming

...缩放整个文本视图。

如果您只想缩放文本,则必须通过捏合手势识别器执行以下步骤:

  • 检索当前属性字符串
  • 遍历字体范围并用缩放的字体替换字体属性
  • 用修改后的版本替换文本视图中的文本
  • 可能你还需要在设置文字后设置文字选择

【讨论】:

  • 您可以提供示例代码来遍历字体范围并增加 uitextview 的属性字符串中的文本大小。我正在尝试这样做。
  • 我没有方便的 ATM,本质上你只需要枚举属性字符串上的字体属性,然后用缩放的替换它。
【解决方案5】:

不是最好但简单的解决方案是:

我不完全了解您的用例,但我认为在许多情况下,在输入文本时支持应用捏缩放是没有意义的。我只想设置一个标志,以防止在用户输入文本时进行缩放。

如果您的意思是输入文本,编辑文本视图可以在捏合手势开始时结束编辑,并在捏合手势结束后开始编辑。

【讨论】:

    猜你喜欢
    • 2011-11-26
    • 1970-01-01
    • 2014-10-23
    • 1970-01-01
    • 1970-01-01
    • 2018-02-03
    • 1970-01-01
    • 2013-07-11
    • 2012-01-29
    相关资源
    最近更新 更多