Resizing UITextView in custom UITableViewCell

匿名 (未验证) 提交于 2019-12-03 02:31:01

问题:

I have a custom UITableViewCell and I'm trying to resize the UITextView inside it based on the content size. I'm on iOS7 and using Autolayout.

I've tried using the following:

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

and

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

from different SO posts. I'm able to resize the frame. But the issue is I'm not able to see the change visibly. In the sense, when I log it, I can see the change. But the UITextView doesnt resize. I cant find any autolayout dependencies either.

When I disabled AutoLayout, it seems to work. How do I do this, by enabling AutoLayout?

Thanks.

EDIT

Here's my UITextView constraints

回答1:

You have to do this calculation in

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; 

method and also resize the cell height accordingly.

If you got it, it's okay. Or If you need the code sample, just ask again. I think you got it !

Updated

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


回答2:

You may forget implement the heightForRowAtIndexPath method of TableView's delegete;

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


回答3:

I think you might have too many constraints for the text view. I can't be sure of this because it's difficult to communicate information about constraints that are built in IB.

Your text view only needs two constraints, one for each axis, in order to be fully constrained. One constraint should position the text view horizontally, the other vertically. The text view's intrinsic content size will be used by the Auto Layout system to automatically generate size constraints for the text view.

I think some of the constraints you have in place now are preventing resizing of the text view. This happens because, by default, constraints you create yourself are required (priority 1000). The automatically-generated sizing constraints, on the other hand, have a lower priority and will be overruled by any conflicting constraints that are required.

Note: just because the text view only needs two constraints to be fully constrained doesn't mean that you can't have more constraints. A table cell with 4 labels, 3 image views, and 1 text view is a complex layout, so you will most likely constrain other UI objects relative to the text view, rather than the superview.



回答4:

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. 



回答5:

Your layout is a bit more complex, but it should not matter if everything is set up properly.

You do not have to calculate anything (by using sizeThatFits).

All you have to do is disable UITextView's scrolling enabled property then on textViewDidChange call tableView.beginUpdates() and tableView.endUpdates(). That doesn't break the first responder and resizes the table view smoothly.

For a detailed explanation, check out a post I wrote which also includes a working sample project.



回答6:

try this

set your UITextView outlet like this in your custom UITableViewCell class

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

hope this will work for you



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