I am using the code below in viewDidLoad:
[self.textView scrollRangeToVisible:NSMakeRange(0, 1)];
set the content offset in viewDidLayoutSubviews for it to take effect
- (void)viewDidLayoutSubviews {
[self.yourTextView setContentOffset:CGPointZero animated:NO];
}
Related
I create a xib file and it includes a UITextView, I add a height constraints for UITextView. When the UIViewController load the xib view I want to change the UITextView height based on the text height. I create an IBOutlet namedheightConstraints for the height constraints and textView for UITextView. I set it in
- (void)viewWillLayoutSubview {
CGFloat height = [self getTextHeight:self.textView];
self.heightConstraints.constant = height;
[self.textView layoutIfNeeded];
}
But it does not change the height of UITextView. Can anyone help?
Can you try
- (void)viewWillLayoutSubview {
self.heightConstraints.constant = self.textView.contentSize.height;
[self.textView layoutIfNeeded];
}
Implement like this, you are required to confirm the UITextView delegate method to change it's height dynamically
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
[self updateTextViewSize:textView];
return YES
}
- (void)updateTextViewSize:(UITextView*)aTextView{
CGFloat height = [self getTextHeight:aTextView];
self.heightConstraints.constant = height;
[self.textView layoutIfNeeded];
}
- (CGFloat)getTextHeight:(UITextView*)aTextView{
/*
calculate frame based on the text and return
*/
}
I have UITextView (textView) in some other view (extView) in my Objective C project with some text in it. The text in textView is quite long so it could by maximised and minimised. Of course, I'd like to do it with some animation.
I change the height of extView with code:
- (void)setExtViewHeight:(CGFloat)newHeight withAnimation:(CGFloat)duration
{
[self setNeedsUpdateConstraints];
[UIView animateWithDuration:duration
animations:^
{
self.extViewHeight.constant = newHeight;
[self layoutIfNeeded];
[self.textView layoutIfNeeded];
}
completion:^(BOOL finished)
{
[self layoutSubviews];
}
];
}
My problem is that animation are actually works only for extView. So when I try to minimise my view the textView jumps to new height and after that extView height is changing with animation. This jump of textView is really annoying and doesn't look good.
What did I do wrong? Why height of textView doesn't follow the animation?
Update your autolayout constant outside of the animation block.
Something like this should work.
Edit: As Duncan C. suggested if you don't want to update the textView height constant as well, you will at least need your textView to have top and bottom relational constraints to your extView
- (void)setExtViewHeight:(CGFloat)newHeight withAnimation:(CGFloat)duration
{
self.extViewHeight.constant = newHeight;
[UIView animateWithDuration:duration animations:^{
[self layoutIfNeeded];
} completion:nil];
}
I'm trying to implement a growing UITextView with the content size, I am using this class and autolayout and it works great but my problem is that my inner scroll view is not scrolling.
It was scrolling before adding the methods for growing text view in viewDidLoad.
This is what is in my xib:
View
outerScrollView
innerScrollView
labels
Growing UITextView
I do this to switch scrolling between scrollview
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
if([scrollView isEqual:self.innerScrollview]){
self.outerScrollview.scrollEnabled = NO;
self.innerScrollview.scrollEnabled = YES;
}
else{
self.outerScrollview.scrollEnabled = YES;
self.innerScrollview.scrollEnabled = NO;
}
}
and in viewDidLoad where the "msg" is the growing textview:
self.msgHandler = [[GrowingTextViewHandler alloc]initWithTextView:self.msg withHeightConstraint:self.msgHeight];
[self.msgHandler updateMinimumNumberOfLines:1 andMaximumNumberOfLine:INT_MAX];
and in textViewDidChange
- (void)textViewDidChange:(UITextView *)textView {
[self.msgHandler resizeTextViewWithAnimation:YES];
}
so why is the growing text affecting the scrolling of the inner scrollview?
int outerContentHeight = self.outer_last_label.frame.size.height + self.outer_last_label.frame.origin.y;
int innerContentHeight = self.inner_last_label.frame.size.height + self.inner_last_label.frame.origin.y;
[self.outerSrollview setContentSize:CGSizeMake([[UIScreen mainScreen] bounds].size.width,outerContentHeight)];
[self.innerScrollview setContentSize:CGSizeMake(self.scrollview2.frame.size.width, innerContentHeight)];
I have managed to fix it but I removed the use of the class"GrowingTextViewHandler" and I did this instead
I changed "scrollViewDidScroll" to this:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
if([scrollView isEqual:self.innerScrollview]){
[self.view insertSubview:self.innerScrollview atIndex:0];
}
else{
[self.view insertSubview:self.outerScrollview atIndex:0];
}
}
and changed "textViewDidChange" to this
- (void)textViewDidChange:(UITextView *)textView {
float height = self.msg.contentSize.height;
[UITextView beginAnimations:nil context:nil];
[UITextView setAnimationDuration:0.5];
self.msgHeightConstraint.constant = height + 10.0; //Give it some padding
[UITextView commitAnimations];
}
Please set the content size of the scroll view, Do not change anything in the code, and check,
[self.scrollViewOuter setContentSize:CGSizeMake(200, 1000)];
[self.scrollViewInner setContentSize:CGSizeMake(200, 1000)];
My both the scroll views are working if, I add content size in it.
I have a scroll view with a label in it, and I wants after someones scroll the label X px's to the right and release his finger to delete this label with animation.
So I created a delegate connection and added the scroll view delegate method:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
NSLog(#"scroll view did scroll");
}
In this method I want to say something like:
if myScrollView.someProperty moved X px's to the right and the user pulled his finger
delete this label sliding with animation to the right
Can someone please help out here :/
tnx ahead!!
Check UIScrollView's contentOffset property:
contentOffset - The point at which the origin of the content view is offset
from the origin of the scroll view.
you can use UISwipeGestureRecognizer to do this and define how many pixel you want to drag the label to the right. You can try the following code
- (void)viewDidLoad {
[super viewDidLoad];
mylabel.userInteractionEnabled=YES;
[mylabel sizeToFit];
[mylabel addGestureRecognizer:[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(didSwipeLabel:)]];
}
- (void)didSwipeLabel:(UISwipeGestureRecognizer*)swipe
{
NSLog(#"swipe");
swipe.direction = UISwipeGestureRecognizerDirectionRight;
if (swipe.direction == UISwipeGestureRecognizerDirectionRight) {
[UIView animateWithDuration:0.5 animations:^{
// swipe the label 50px right
mylabel.transform = CGAffineTransformMakeTranslation(50.0, 0.0);
} completion:^(BOOL finished) {
// when animation
[UIView animateWithDuration:0.5 animations:^{
NSLog(#"label should be removed");
[mylabel removeFromSuperview];
}];
}];
}
}
I would like to create an app that has a function like iOS 7's Notes application. Basically there is one row on the top that has date and time.
My solution is to put the UITextView inside UITableView. First row is UILabel with date and time, the second row is UITextView.
I change both UITextView and UITableViewCell height according to UITextView ContentSize.
The problem is the UITextView size is large so it doesn't automatically scroll when the user hit return key.
Is there any solution to make it scroll as normal?
UITextView is a subclass of UIScrollView. I will suggest an alternative method of implementing a similar functionality. Add the label view as a subview of the text view, and set a contentInset top value of the height of the label.
UILabel* label = [UILabel new];
label.text = #"Test";
[label sizeToFit];
CGRect frame = label.frame;
frame.origin.y -= frame.size.height;
[label setFrame:frame];
[self.textView addSubview:label];
[self.textView setContentInset:UIEdgeInsetsMake(label.frame.size.height, 0, 0, 0)];
Sample project:
http://sdrv.ms/16JUlVD
Try this solution. Fix is based on inheritance. But logic can be used at any place after UITextView text was changed. I have taken some useful code blocks from here:
http://craigipedia.blogspot.ru/2013/09/last-lines-of-uitextview-may-scroll.html
and edited by me for my solution.
Should work.
#interface CustomTextView : UITextView
#end
#implementation CustomTextView
-(id)init {
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textDidChange:) name:UITextViewTextDidChangeNotification object:self];
}
return self;
}
-(void)textDidChange:(NSNotification *)notification {
//iOS 7 UITextView auto scroll fix.
NSRange caretRange = self.selectedRange;
if (caretRange.location == self.text.length) {
CGRect textRect = [self.layoutManager usedRectForTextContainer:self.textContainer];
CGFloat sizeAdjustment = self.font.lineHeight * [UIScreen mainScreen].scale;
if (textRect.size.height >= self.frame.size.height - sizeAdjustment) {
if ([[self.text substringFromIndex:self.text.length - 1] isEqualToString:#"\n"]) {
[UIView animateWithDuration:0.2 animations:^{
[self setContentOffset:CGPointMake(self.contentOffset.x, self.contentOffset.y + sizeAdjustment)];
}];
}
}
}
//end of fix
}
#end