rrdev
rrdev

Reputation: 65

iOS - Scroll TextView to top when it's in a tableview cell

I have a UITextView inside a custom TableView cell. I want the text view to scroll to the top by default. I usually do it this way in regular views:

override func viewDidLayoutSubviews() {

    super.viewDidLayoutSubviews()
    let fixedWidth = bioView.frame.size.width
    bioView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
    let newSize = bioView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
    var newFrame = bioView.frame
    newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
    bioView.frame = newFrame;
    bioView.scrollRangeToVisible(NSRange(location:0, length:0))
}

bioView is my text view object. However, this doesn't work in my case since I can't reference the textview in the ViewController class and can only do so in the CustomCell class and that class cannot override viewDidLayoutSubviews. Any help?

Upvotes: 3

Views: 1681

Answers (3)

DrSmart
DrSmart

Reputation: 381

I have tried doing the scrolling, either with scrollRangeToVisible() or setting contentOffset to .zero in awakeFromNib, willDisplayCell, and cellForRowAtIndexPath. These all get executed, but the scrolling is still reset (by AutoLayout?) some time subsequent to this.

For a cell that is on screen when the UITableView appears, performing the scroll in willDisplayCell does not "stick." It does work if the cell is scrolled away and scrolls back on screen.

For a cell that is already on screen that has a UITextView with "too much" text so that it scrolls out the bottom of the TextView, the only way I have found to make the text scroll to the top is to set either scrollRangeToVisible() or contentOffset in the viewDidAppear() of the UITableViewController. Even viewWillAppear() did not work.

One drawback is that this solution causes a jump in the scroll location after the TableView appears on screen, even in a performWithoutAnimation block.

You can put the code in viewDidLayoutSubviews, and it will work, but as mentioned this gets called several times, and the text will scroll back to the top with every orientation change, which may not be desirable.

Upvotes: 0

Amit Tandel
Amit Tandel

Reputation: 883

Try this.

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CustomCell* cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell"];
    [cell.textView scrollRangeToVisible:NSMakeRange(0, 0)];
    return cell;
}

Swift 3.0:

    let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! DemoCell
    cell.textView.scrollRangeToVisible(NSRange(location:0, length:0))

It works! However, the table has to scroll for the changes to take effect, best way I found so far. Thanks everyone!

Upvotes: 1

Apurv
Apurv

Reputation: 17186

In your viewController which handles UITableViewDelegate events, override willDisplayCell method. Identify your textView from Cell and write the code to scroll.

Upvotes: 0

Related Questions