【问题标题】:Scroll UITextView To Bottom将 UITextView 滚动到底部
【发布时间】:2013-05-17 21:51:02
【问题描述】:

我正在制作一个具有UITextView 和按钮的应用程序。

当我单击按钮时,一些文本将添加到 UITextView

但是当点击按钮时,我不想向下滚动到文本字段的底部,以便用户可以看到最后添加的文本。

如何让UITextView向下滚动到底部?

我试过了:

int numLines = LogTextView.contentSize.height / LogTextView.font.lineHeight+1;
NSLog(@"%d",numLines);

NSUInteger length = self.LogTextView.text.length;
self.LogTextView.selectedRange = NSMakeRange(0, length);

但它不会工作......

我也试过了:

self.LogTextView.contentSize=CGSizeMake(length,0);

【问题讨论】:

  • 首先是文本视图,因为一个UITextView,因为文本字段没有滚动。 ;) 也许你可以使用scrollRangeToVisible 方法:)
  • 正如@danypata 所质疑的,这是一个uitextview,还是uiscrollview 中的一个uitextfield?您在问题中引用了文本字段和文本视图。
  • @andrewlattis 问题是关于UITextView,它是UIScrollView 的一个子,contentSize 是一个属性。

标签: ios uitextview


【解决方案1】:

如果你说的是 UITextView,你可以使用下面的代码:

-(void)scrollTextViewToBottom:(UITextView *)textView {
     if(textView.text.length > 0 ) {
        NSRange bottom = NSMakeRange(textView.text.length -1, 1);
        [textView scrollRangeToVisible:bottom];
     }

}

SWIFT 4:

func scrollTextViewToBottom(textView: UITextView) {
    if textView.text.count > 0 {
        let location = textView.text.count - 1
        let bottom = NSMakeRange(location, 1)
        textView.scrollRangeToVisible(bottom)
    }
}

【讨论】:

  • 不要忘记添加 [textView setScrollEnabled:NO]; [textView setScrollEnabled:YES];
  • @ofirmalachi,您的意思是在上面的评论中写出相互矛盾的陈述吗?
【解决方案2】:

如果您在 iOS 7 或更高版本上遇到问题,请尝试此操作。见this SO answer

- (void)scrollTextViewToBottom:(UITextView *)textView {
    NSRange range = NSMakeRange(textView.text.length, 0);
    [textView scrollRangeToVisible:range];
    // an iOS bug, see https://stackoverflow.com/a/20989956/971070
    [textView setScrollEnabled:NO];
    [textView setScrollEnabled:YES];
}

【讨论】:

  • IOS 13,bug 还在!
【解决方案3】:

使用 Swift 3

let bottom = self.textView.contentSize.height - self.textView.bounds.size.height
self.textView.setContentOffset(CGPoint(x: 0, y: bottom), animated: true)

【讨论】:

  • 它应该可以工作。您在哪里使用此代码?确保在加载 textView 后使用它。
  • 在 viewDidAppear 之后,textview 已完全加载,有内容。可能与 textview 的内容比屏幕的边界大很多有关
  • 我刚刚重新验证,它工作得很好。我创建了一个新的单视图项目,拖放一个具有默认大小和默认文本的 textView,连接插座,将此代码放在 viewDidAppear 中。它正确地滚动到底部。
  • 最好加上检查底部是否为正,因为如果为负则不需要更改contentOffset。
  • 对我不起作用(iOS11)。我的文本跨越多行并使用自定义字体。
【解决方案4】:

斯威夫特 5

extension UITextView {
    func simple_scrollToBottom() {
        let textCount: Int = text.count
        guard textCount >= 1 else { return }
        scrollRangeToVisible(NSRange(location: textCount - 1, length: 1))
    }
}

// Usage
textView.simple_scrollToBottom()

【讨论】:

  • 优秀推荐!效果很好。将扩展名放在类 } 之后的代码底部,然后使用 //Usage.按钮 Action 中的代码。
  • 将此更改为 swift 5 scrollRangeToVisible(NSRange(location: textCount - 1, length: 1))
  • 感谢@AMAN77 我已插入您的更改。
【解决方案5】:

你必须实现一个委托方法。下面的代码检查是否输入了换行符,如果是,则滚动到 textView 的底部:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{

    if ([text isEqualToString:@"\n"]) {
        textView.contentOffset = CGPointMake(0.0, textView.contentSize.height);
    }
    return YES;
}

【讨论】:

    【解决方案6】:

    创建一个范围,指定编码,到最后一个字符,然后滚动到该范围 utf8 以外的其他内容可能适合您的内容

    let range = NSMakeRange(self.textView.text.lengthOfBytes(using: .utf8), 0);
    self.textView.scrollRangeToVisible(range);
    

    【讨论】:

    • 所有延迟最小的最佳解决方案!
    • 这也适用于 iOS 14.4。流畅,完全没有问题
    【解决方案7】:

    这对我有用! :D

    CGPoint bottomOffset = CGPointMake(0, self.textView.contentSize.height - self.textView.bounds.size.height);
    [self.description1 setContentOffset:bottomOffset animated:YES];
    

    【讨论】:

    • 这适用于您需要在没有动画的情况下执行此操作(当然有动画:NO)。请注意,您可能需要添加 max(0, ... 以仅在必要时向下滚动。
    【解决方案8】:

    作为滚动到底部的通用方法,它可以在 UIScrollView 上完成。

    extension UIScrollView {
        func scrollToBottom() {
            let contentHeight = contentSize.height - frame.size.height
            let contentoffsetY = max(contentHeight, 0)
            setContentOffset(CGPoint(x: 0, y: contentoffsetY), animated: true)
        }
    }
    

    这将适用于 UIScrollView 的所有后代,如 UITextView、UITableView 等。

    【讨论】:

      【解决方案9】:
      textView.scrollRangeToVisible(NSRange(..<textView.text.endIndex, in: textView.text))
      

      这个解决方案做了几个值得注意的事情,略有不同:

      • 利用String.Index 接口(可能比.count 等性能更高)
      • 使用 PartialRangeUpTo 避免显式范围起始位置,从而将代码简化为简洁的单行代码

      【讨论】:

        【解决方案10】:

        @Hong Duan answer 的 Swift 版本

        func scrollTextViewToBottom(textView: UITextView) {
            if textView.text.count > 0 {
                let location = textView.text.count - 1
                let bottom = NSMakeRange(location, 1)
                textView.scrollRangeToVisible(bottom)
        
                // an iOS bug, see https://stackoverflow.com/a/20989956/971070
                textView.isScrollEnabled = false
                textView.isScrollEnabled = true
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-09
          • 1970-01-01
          • 2013-01-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多