在自定义UITableViewCell中调整UITextView的大小

时间:2013-12-09 08:55:33

标签: ios objective-c uitableview

我有自定义UITableViewCell,我正在尝试根据内容大小调整其中UITextView的大小。我在iOS7上使用Autolayout。

我尝试过使用以下内容:

[cell.question setScrollEnabled:YES];
[cell.question sizeToFit];
[cell.question setScrollEnabled:NO];

- (CGRect)textViewHeightForAttributedText: (NSAttributedString*)text andWidth: (CGFloat)width
{
    UITextView *calculationView = [[UITextView alloc] init];
    [calculationView setAttributedText:text];
    CGSize size = [calculationView sizeThatFits:CGSizeMake(width, FLT_MAX)];
    CGRect finalFrame = CGRectMake(0, 0, width, size.height);
    return finalFrame;
}

来自不同的SO帖子。我能够调整框架的大小。但问题是我无法看到明显的变化。从某种意义上说,当我记录它时,我可以看到变化。但UITextView没有调整大小。我也找不到任何自动布局依赖项。

当我禁用AutoLayout时,它似乎有效。如何启用AutoLayout?

感谢。

修改

这是我的UITextView约束

Screenshot

6 个答案:

答案 0 :(得分:2)

您必须在

中进行此计算
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

方法并相应地调整单元格高度。

如果你明白了,那没关系。或者如果您需要代码示例,请再次询问。 我想你明白了!

<强>更新

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
            UITextView *tempTV = [[UITextView alloc] init];
            [tempTV setText:@"your text"];
            CGFloat width = self.tableView.frame.size.width - TEXT_ORIGIN_X - TEXT_END_X;
            CGSize size = [tempTV sizeThatFits:CGSizeMake(width, MAX_HEIGHT)];
            return (TEXT_ORIGIN_Y + size.height + TEXT_BOTTOM_SPACE);
    }

答案 1 :(得分:0)

您可能忘记实现TableView委托的heightForRowAtIndexPath方法;

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CGFloat  yourTextViewsHeight = ... calculate it here
    return yourTextViewsHeight;
}

答案 2 :(得分:0)

我认为你可能对文本视图有太多限制。我无法确定这一点,因为很难传达IB中构建的约束信息。

您的文本视图只需要两个约束,每个轴一个约束,以便完全约束。一个约束应该水平定位文本视图,另一个约束垂直定位。 Auto Layout系统将使用文本视图的内在内容大小自动为文本视图生成大小约束。

我认为您现有的一些限制因素阻止了文本视图的大小调整。发生这种情况是因为,默认情况下,您自己创建的约束是必需的(优先级1000)。另一方面,自动生成的大小调整约束具有较低的优先级,并且将被所需的任何冲突约束所推翻。

注意:仅仅因为文本视图只需要两个约束来完全约束并不意味着你不能拥有更多的约束。具有4个标签,3个图像视图和1个文本视图的表格单元格是一个复杂的布局,因此您很可能相对于文本视图而不是超级视图限制其他UI对象。

答案 3 :(得分:0)

I had the same issue but in a different situation. I have UItableview with two custom cells.

First Custom cell - self expanding textview. (like email type message box)
Second Custom Cell -  Static image. 

Have a  look at my code. You will get an insight to automatic resizing of cells.

//  ViewController.swift
//  ListWrap

import UIKit

class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate, UITextViewDelegate {

    @IBOutlet var listWrapTableView: UITableView!

    //CustomCells
    var CellIdentifier: String = "ListWrapTableViewCellID"
    var tapGesture: UITapGestureRecognizer!

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    override func viewWillAppear(animated: Bool) {
        //Adding Tap Gesture To Table
        tapGesture = UITapGestureRecognizer(target: self, action: "tapRecognized:")
        self.listWrapTableView.addGestureRecognizer(tapGesture)
        tapGesture.cancelsTouchesInView = false
        tapGesture.enabled =  true
    }
    func tapRecognized(recognizer: UITapGestureRecognizer){
        self.listWrapTableView.endEditing(true)
    }
    func textViewDidBeginEditing(textView: UITextView) {
        if (CellIdentifier == "ListWrapTableViewCellID")
        {
            tapGesture.enabled =  true
        }
        else
        {
            tapGesture.enabled =  false
        }
    }
    // MARK: - Table view data source
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
    func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
    {
        self.listWrapTableView.rowHeight = UITableViewAutomaticDimension
        return self.listWrapTableView.rowHeight
    }
    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 2
    }
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        if (indexPath.row == 0)
        {
            let surveyCell = tableView.dequeueReusableCellWithIdentifier(CellIdentifier)! as! ListWrapTableViewCell
            return surveyCell
        }
        else if (indexPath.row == 1)
        {
            let reportsCell = tableView.dequeueReusableCellWithIdentifier("ListWrapSecondTableViewCellID")! as! ListWrapSecondTableViewCell
            return reportsCell
        }
        else
        {
            let cell:UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "")
            return cell
        }
    }
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
    {
    }
}



The first Custom cell:

//  ListWrapTableViewCell.swift
//  ListWrap

import UIKit

class ListWrapTableViewCell: UITableViewCell{

    @IBOutlet var listWrapTextView: UITextView!

//
//  override init?(style: UITableViewCellStyle, reuseIdentifier: String!) {
//      super.init(style: style, reuseIdentifier: reuseIdentifier)
//  }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
    }

    /// Custom setter so we can initialise the height of the text view
    var textString: String {
        get {
            return listWrapTextView.text
        }
        set {
            listWrapTextView.text = newValue
            textViewDidChange(listWrapTextView)
        }
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        listWrapTextView.scrollEnabled = false
        listWrapTextView.delegate = self
    }
    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        if selected {
            listWrapTextView.becomeFirstResponder()
        } else {
            listWrapTextView.resignFirstResponder()
        }
    }
}
extension ListWrapTableViewCell: UITextViewDelegate {
    func textViewDidChange(textView: UITextView) {

        let size = textView.bounds.size
        let newSize = textView.sizeThatFits(CGSize(width: size.width, height: CGFloat.max))

        // Resize the cell only when cell's size is changed
        if size.height != newSize.height {
            UIView.setAnimationsEnabled(false)
            tableView?.beginUpdates()
            tableView?.endUpdates()
            UIView.setAnimationsEnabled(true)

            if let thisIndexPath = tableView?.indexPathForCell(self) {
                tableView?.scrollToRowAtIndexPath(thisIndexPath, atScrollPosition: .Bottom, animated: false)
            }
        }
    }
}
extension UITableViewCell {
    /// Search up the view hierarchy of the table view cell to find the containing table view
    var tableView: UITableView? {
        get {
            var table: UIView? = superview
            while !(table is UITableView) && table != nil {
                table = table?.superview
            }

            return table as? UITableView
        }
    }
}

The second custom cell: 

//  ListWrapSecondTableViewCell.swift
//  ListWrap


import UIKit

class ListWrapSecondTableViewCell: UITableViewCell {

    override func awakeFromNib() {
        super.awakeFromNib()
    }
    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }

}


attaching storyBoard for further reference.

enter image description here

答案 4 :(得分:0)

您的布局有点复杂,但如果一切设置正确,则无关紧要。

您无需计算任何内容(使用sizeThatFits)。

您所要做的就是禁用UITextView的滚动启用属性,然后禁用textViewDidChange调用tableView.beginUpdates()和tableView.endUpdates()。这不会破坏第一个响应者并平滑地调整表格视图的大小。

有关详细说明,请查看post I wrote,其中还包含一个工作示例项目。

答案 5 :(得分:-1)

试试这个

在您的自定义UITableViewCell类中设置您的UITextView插座

[yourTextView setAutoresizesSubviews:YES];
yourTextView.autoresizingMask = UIViewAutoresizingFlexibleWidth;

希望这对你有用