Scroll bar visibility in iOS - ios

I got stuck where I need to display my UITextView's scroll bar permanently i.e. scroll bar should not disappear. I tried [textview flashScrollIndicators]; for this but it doesn't make any difference. Is there any way to do this?

[textView flashScrollIndicators];
UITextView inherit UIScrollView. As UIScrollView has a method flashScrollIndicators to show the scroll bar that you can call to prompts the user that the view is scrollable. Note, It only flashes once for few seconds where user comes to a page that contains UIScrollView or its subclass. As you want to show the scroll bar permanently show you can use a timer to call this method.
[NSTimer scheduledTimerWithTimeInterval:2.0f target:self selector:#selector(showAgain) userInfo:nil repeats:YES];
-(void)showAgain
{
[myTextView flashScrollIndicators];
}
NB: UITextView only start showing the scroller when it's content size get overflow then it's height. And there after [textView flashScrollIndicators] this method will work.

No there is no way to have them always display. Also they're scroll indicators and not scroll bars.
You could setup a timer to flashScrollIndicators at a given time suited to your app such as when the view appears or when some text input is detected using the UITextView's delegates.
I haven't tried using this custom component but since the UITextView is a subclass of UIScrollView, you could explore the possibility of tinkering with it and see if it works for you.

Try to set flashIndicators in viewDidAppear or viewDidLoad
-(void)viewDidAppear:(BOOL)animated {
[self.textView flashScrollIndicators];
}

Related

How to prevent iOS from resizing your UIViewController's view after return from background

I have a UIViewController that displays a form with several text fields. In order to prevent the text fields from getting blocked by the keyboard, I resize the controller's view when the keyboard appears and disappears.
However, when the keyboard is up, the user presses the home button, and then returns to the app, the controller's view will be resized again to the size it was before the keyboard was up and the keyboard will still be showing.
What's causing my controller's view to be resized on return from background, and how can I prevent it?
Maybe you need to nest a UIView,for example
_backgroundView = [UIView new];
_backgroundView.backgroundColor = [UIColor whiteColor];
_backgroundView.frame = CGRectZero;
[self.view addSubview:_backgroundView];
[_backgroundView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.top.mas_equalTo(self.view);
make.height.mas_equalTo(self.view.mas_height);
}];
then you need add your custom UIView to this backgroundView.
as you said,UIViewController's view will be resized after return from background. so you can nest a UIView of the same size as self.view,and add your custom UIView to this UIView.
In order to prevent the text fields from getting blocked by the keyboard, you can resize this backgroundView when the keyboard appears and disappears. and this time when you click the home button to enter the background or return from background,self.view won't be resized and backgroundView won't be resized too.
Although it is a bit of a hassle, this will solve your problem and will not affect the user experience anymore. And if you have a better solution, please let me know
It sounds like you are setting the frame and not using autolayout. When the view reappears viewDidLayoutSubviews gets called and your frame gets recalculated obliterating your previous change. You can either:
1) Move your frame to viewDidLayoutSubviews and change its size only if the keyboard is showing.
2) Use autolayout and simply pull up your bottom constraint .constant by an amount equal to your keyboard height.
In both cases you should call layoutIfNeeded to trigger autolayout/viewDidLayoutSubviews when the keyboard appears/disappears. This behavior is a good example of why you should not manipulate your frames outside of viewDidLayoutSubviews except for transitory animations.

UITextView content going under UINavigationBar

I have a UITextView inside a UIViewController that uses auto layout to pin it to 0 on all sides (so it fills the whole screen). I also have this view being pushed using UINavigationController.
I'm running into a weird error where if the UITextView has enough text so that it runs off the screen, then content gets set under the UINavigationBar. If there is not enough text to fill the screen the layout of the text doesn't go under the UINavigationBar.
Here is what's happening, this is when there is enough text that it goes off the screen and you need to scroll to view all of it.
I've tried:
Setting the content inset of the UITextView.
Made sure the UINavigationBar isn't translucent.
Tried setting this self.automaticallyAdjustsScrollViewInsets = NO;
Inside viewDidLoad of viewController where your textView is, add this:
self.edgesForExtendedLayout = UIRectEdgeNone;
I'm not sure why the problem was occurring but this fixed it:
- (void)viewDidLayoutSubviews {
if (self.textView) {
[self.textView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
}
}

iOS uilabel stay on screen when scrolling

In my app I was giving some information like "connection error" or "image saved" when users
caused some events. Instead of using alert view, I'd like to show labels with those text
on screen for
about 2-3 secs and disappear automatically.
Most like what Android apps would do like this.
(sorry for a link rather than post image due to low rep.)
As I did [superView addSubview:label] my label was attached on the back view and moved by scrolling.(superView = tableView)
How could I keep it at a fixed position of screen when user's scrolling it's superView?
prefer simple solution without using 3rd party...
tho any advance would be appreciated.
just add a label to the superview and make it hidden
label.hidden = YES; // write this in viewDidLoad()
And in event action unhide the label
label.hidden = NO;
and then set a timer so that after 2 or 3 second the label will disapear.
//inside event action
[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:#selector(hideLabel) userInfo:nil repeats:NO];
and in the selector method write code for hiding the label
- (void) hideLabel
{
_lblClick.hidden = YES;
}
I hope this is what you want......
After you add the view to your superView , You can use the [superView bringSubviewToFront:<#(UIView *)#>] method. This will block some of your scrollView scrolling space, but will keep your label in the frontmost part of your view.
You can use UIView's animation to add to show and hide the label
Don't add the label to scrolling superView. Instead add it to parent of superView or the viewControllers primaryView(by default self.view) and use hidden property. Use autolayout to position the label for various layouts.

UISearchbar vanishes when in UIScrollView

I seem to be having an issue with the UISearchbar in iOS 7 vanishing in two scenarios. First the controller is fairly simple it has a nib which contains a scrollview which has in it the uisearch bar and some content. The ui search bar is at the top of the scrollview. So when I scroll the scrollview so the uisearchbar is longer visible and I exit and reneter the controller the uisearch bar is longer visible. Clicking the region makes it appear again. The uisearchbar also vanishes when I double tap it quickly. This controller worked fine is iOS 6 these issues are only happening now that I am building for ios 7
Edit
Investigating the double tap issue causing the uisearchbar to disappear. It seems that the uisearch bar when double tapped quickly is removing the uisearchbar from the view hierarchy when displaying it but never readding it back when it has been dismissed. So I can workaround that by doing
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller
{
// workaround for bug in ios 7 were quickly double tapping uisearchbar (e.g it appears and get dismissed quickly)
// does not re add the uisearch bar to the correct view.
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0")) {
UIView *parentView = [self.scrollView.subviews objectAtIndex:0];
[parentView addSubview:self.searchDisplayController.searchBar];
}
return;
}
Have you tried doing some UI refresh stuff?
Like:
- (void)viewWillAppear:(BOOL)animated{
[self.scrollView setNeedsLayout];
}

Weird interface bug UIScrollView in UITabBarController. Reproducible by others?

I get a weird interface bug with my UIScrollView and I cant figure out how to solve it. I only wrote one line of code (shown below) and it is a blank project's setup easily reproducible!
Setting:
I have a UIScrollView that contains a UISegmentedControl (since the segments of
the control are loaded dynamically, it could exceed the width of the screen and the scrollView is supposed to scroll the segmentedControl horizontally, the height of the scrollview is the same as the UISegmentedControl's).
The ViewController that contains this is embedded in a tabBar (or navigation bar, which also shows the bug). The whole thing is using Auto-Layout.
Bug:
When I scroll the SegmentedControl some degree to the right and then switch the viewController by clicking the other tab on the tabBarController, the content-offset of the segmented control gets weirdly shifted when switching back to the initial viewcontroller. When I try to scroll to the leftmost part of the scrollview it won't let me. When switching the tabs a couple of times, it gets fixed again and I can do this over.
What I did (can you reproduce this?):
Create a blank single-view ios project
Embed the already given viewController in a tabbarcontroller.
Put a scrollView on the upper portion of the view that fits the screen from left to right.
Put a UISegmentedControl on the topleft corner of the scrollview and drag the scrollview to fit the segmented controls height height
Change the Segmented control's width a bit so xcode adds a width-constraint. in the segmented control's width constraint change the width constraint's relation to "greater than or equal"
create an outlet to the segmented control
in viewDidload add this code
[self.segmentedControl insertSegmentWithTitle:#"A really long title so it you have to scroll to see it" atIndex: 0 animated: NO];
Create a blank viewcontroller and add it as a second viewController for the tabbarController.
This is how my storyboard looks like:
Now run the project, scroll the segmented control to it's right end as far as it goes. Switch the tab and switch back and please tell me how your scrollview now behaves - and WHY.
My guess would be it has something to do with Auto Layout maybe? Can't figure out what though.
I tried fixing this by setting the scrollView's contentSize in viewDidAppear or changing the content offset of the scrollView in viewDidAppear or changing frames, combination of those and what not....
Extra question:
Is it no longer neccessary to set the scrollViews contentSize property? Why does it scroll the content automatically?
After googeling I found the answer in another StackOverflow question.
What you need to do is save the scrollview.contentOffset on viewWillDisappear,
set it to CGPointZero on viewDidDisappear and set it back to the saved state on viewDidLayoutSubviews:
-(void) viewWillDisappear: (BOOL) animated {
self.lastContentOffset = self.scrollView.contentOffset;
[super viewWillDisappear: animated];
}
-(void) viewDidDisappear:(BOOL)animated {
[super viewDidDisappear: animated];
self.scrollView.contentOffset = CGPointZero;
}
- (void)viewDidLayoutSubviews {
[super viewDidlayoutSubviews];
self.scrollView.contentOffset = self.lastContentOffset;
}

Resources