I have a UITextView in a UITableViewCell. I'm trying to dynamically size the textView.
-(void)textViewDidChange:(UITextView *)textView
{
CGFloat fixedWidth = textView.frame.size.width;
CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
CGRect newFrame = textView.frame;
newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
textView.frame = newFrame;
[self.myTableView beginUpdates];
[self.myTableView endUpdates];
}
After every char I input, the whole view jumps to the top, then jumps right back down to where I was at.
The solution for that, is probably to take away begin/endUpdates. When I do that, the textView sizes itself correctly, but the cell's height doesn't change.
Qustion:
How can I make the textView and the tableVIewCell dynamically size itself?
You need to reload only that particular cell in which the TextView is added.
Try this
[self.myTableView beginUpdates];
[self.myTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPathOfYourCell] withRowAnimation:UITableViewRowAnimationNone];
[self.myTableView endUpdates];
Related
I use below code to resize collection view cells that works fine.
- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
UICollectionViewLayoutAttributes *attributes = [super preferredLayoutAttributesFittingAttributes:layoutAttributes];
CGRect newFrame = attributes.frame;
[self setNeedsLayout];
[self layoutIfNeeded];
CGSize desiredSize = [self systemLayoutSizeFittingSize:UILayoutFittingCompressedSize withHorizontalFittingPriority:UILayoutPriorityRequired verticalFittingPriority:UILayoutPriorityDefaultLow];
newFrame.size = CGSizeMake([UIScreen mainScreen].bounds.size.width, desiredSize.height);
attributes.frame = newFrame;
return attributes;
}
But when I use or call [collectionView reloadData]
the collection view is scrolled automaticaly to the top of the collection view.
Please help me out with it.
This is what I am doing so as to set the focus on the same point after UITableView beginUpdates :
CGPoint offset = tableMessageDetail.contentOffset;
// CGPoint textPoint = [self.view convertPoint:cell.txtReply.frame.origin toView:nil];
[tableMessageDetail beginUpdates];
[tableMessageDetail endUpdates];
[tableMessageDetail setContentOffset:offset animated:NO];
//[tableMessageDetail scrollRectToVisible:CGRectMake(cell.frame.origin.x, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height) animated:YES];
But the position after endUpdates, when the cell is too high, comes to the top of cell. I have tried with the commented approach as well, but that too is not perfect.
Giving a thought, hope this helps:
Remove all animations on the tableView's layer before setting the contentOffset.
[tableView.layer removeAllAnimations];
[tableView setContentOffset:offset animated:NO];
and then,
[tableView scrollToRowAtIndexPath:cell.indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
I have a UITextView in custom UITableViewCell. On expanding the UITextView, I want the subviews below the UITextView to fall as per its height and also increase the row height. For this I am doing :
- (void)textViewDidChange:(UITextView *)textView
{
int numLines = textView.contentSize.height/textView.font.lineHeight;
if(numLines < 6)
{
CGRect frame = textView.frame;
frame.size.height = textView.contentSize.height;
textView.frame = frame;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(int)textView.tag inSection:0];
MessageDetailCell *cell = [tableMessageDetail cellForRowAtIndexPath:indexPath];
cell.txtReplyHeightConstraint.constant = textView.frame.size.height;
[cell updateConstraintsIfNeeded];
[cell setNeedsLayout];
[cell layoutIfNeeded];
[tableMessageDetail beginUpdates];
[tableMessageDetail endUpdates];
}
}
Everything works fine except that beginUpdates endUpdates makes the UITableViewCell flash. So far as cell content is concerned, I have images as well as text displayed in it. The cell flashed only in case of images.
You have to call beginUpdates before you change the frame.
[tableMessageDetail beginUpdates];
// change cell attributes
[tableMessageDetail endUpdates];
I have a UITextView in a UITableViewCell in the storyboard. I then added a constraint on all 4 sides of the UITextView.
In the code below I tried making the textView dynamically change as the user enters text. I'm pretty sure that worked successfully. But the problem is the cell is not. Bellow is the code I tried, without success.
-(void)viewDidLoad
{
tableView.rowHeight = UITableViewAutomaticDimension;
tableView.estimatedRowHeight = 44;
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if (textView == myTextView)
{
[self textViewFitToContent:myTextView];
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:#[[NSIndexPath indexPathForItem:1 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
}
return YES;
}
- (void)textViewFitToContent:(UITextView *)textView
{
CGFloat fixedWidth = textView.frame.size.width;
CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
CGRect newFrame = textView.frame;
newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
textView.frame = newFrame;
textView.scrollEnabled = NO;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return myTextView.frame.size.height + 40;
}
I'm a beginner so please don't be too harsh on me.
Thanks
Your code is fine, flawless infact and quite well done. Without seeing your declared variables, I believe the reason that the cell isn't resizing is because you're heightForRowAtIndexPath method is returning the height of the wrong UITextView. Instead of txtSymptoms which isn't used anywhere else in the resizing code, you should be using myTextView instead, which, when the user edits the text of, will trigger the tableView to reload.
This snippet of yours:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return myTextView.frame.size.height + 40;
}
From the rest of your code, myTextView seems to be a special text view that you are adding text to and resizing, but this method uses that larger height for sizing, which is why all of your cells grow taller.
In the storyboard, select your text view and in the size inspector look for the content hugging priority option.
Content hugging priority can range from 0 to 1000.
Keep the content hugging priority of your text view (for vertical section especially) higher than the content hugging priority of the content view of the cell in which the text view resides.
I have a UITextView in a UITableViewCell. They both dynamically size itself to fit. The problem I have is that when the texview reaches below the bottom of the screen (from making new lines), the tableView does not scroll to its location.
I tried this code, but it didn't work.
- (void)textViewDidChangeSelection:(UITextView *)textView {
[textView scrollRangeToVisible:textView.selectedRange];
}
You can find the cell containing the textView and tell the table view to scroll to that cell:
UIView *parentView = textView.superview;
while(![parentView isKindOfClass:[UITableViewCell class]]) {
parentView = parentView.superview;
}
NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell*)parentView];
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
You should add code below to scroll the tableView too:
- (void)textViewDidChangeSelection:(UITextView *)textView {
[textView scrollRangeToVisible:textView.selectedRange];
// since you are only scrolling the table a little bit and not by a whole cell, then change the scrollView.offset
CGPoint offset = tableView.contentOffset;
offset.x += 20; // an example. You need to change this based on the new size of the textview.
tableView.contentOffset = offset;
}