2009-12-11 3 views
53

Возможно, простой!UIScrollView - показывает полосу прокрутки

Кто-нибудь знает, как можно постоянно показывать полосу прокрутки UIScrollView?

Он показывает, когда пользователь прокручивает, чтобы они могли увидеть, что положение точки зрения прокрутки они находятся.

НО Я хотел бы, чтобы постоянно показывать, потому что это не сразу видно пользователю, что скроллинг доступно

Любые советы будут высоко оценены.

ответ

82

Нет, вы не можете заставить их всегда показывать, но вы можете заставить их временно мигать.

[myScrollView flashScrollIndicators]; 

Это индикаторы прокрутки, а не полосы прокрутки. Вы не можете использовать их для прокрутки.

+2

Правильно, это было бы непоследовательно, если бы они были там все время. Это правильный подход. –

+1

Если у вас есть контроль над содержимым, вы можете дать пользователям понять, что контент прокручивается, если часть содержимого перекрывает границы. Как изображение, показывающее только часть, которая будет предлагать больше контента. Затем пользователь может экспериментировать и прокручивать, чтобы увидеть больше. – Sophtware

+1

Не работает для [UIWebView.scrollView] :( – Dmitry

4

Насколько я знаю, это невозможно. Единственный вызов API, который управляет отображением индикатора прокрутки, - showsVerticalScrollIndicator, и это может только отключить отображение индикатора в целом.

Вы можете указать flashScrollIndicators, когда появится представление, чтобы пользователь знал, где находится вид прокрутки.

0

Для просмотра веб-страниц, где первое подвью является прокруткой, в последнем SDK, если HTML-страница длиннее, чем рамка, не отображается полоса прокрутки, и если содержание html происходит в соответствии с фреймом или у вас есть пробел в нижней части рамки, он «выглядит», как будто нет прокрутки и ничего ниже строки. В этом случае, я думаю, вы должны определенно прошить полосы прокрутки в

- (void)webViewDidFinishLoad:(UIWebView *)webView; 

метод делегата, чтобы предупредить пользователя о том, что есть больше вещей «вне коробки».

NSArray *subViews = [[NSArray alloc] initWithArray:[webView subviews]] ; 
UIScrollView *webScroller = (UIScrollView *)[subViews objectAtIndex:0] ;  

С помощью HTML горизонтальное содержимое обернуто автоматически, поэтому проверьте высоту веб-браузера.

 if (webScroller.contentSize.height > webView.frame.size.height) { 
      [webScroller flashScrollIndicators]; 
     } 

Вспышка настолько короткая, что происходит при просмотре изображений, что ее можно упускать из вида. Чтобы обойти это, вы могли бы также покачивание или подпрыгивать или прокручивать и масштабировать Контент немного через родового UIView commitAnimations

6

my solution индикаторы прокруток показывают все время

#define noDisableVerticalScrollTag 836913 
#define noDisableHorizontalScrollTag 836914 

@implementation UIImageView (ForScrollView) 

- (void) setAlpha:(float)alpha { 

if (self.superview.tag == noDisableVerticalScrollTag) { 
    if (alpha == 0 && self.autoresizingMask == UIViewAutoresizingFlexibleLeftMargin) { 
     if (self.frame.size.width < 10 && self.frame.size.height > self.frame.size.width) { 
      UIScrollView *sc = (UIScrollView*)self.superview; 
      if (sc.frame.size.height < sc.contentSize.height) { 
       return; 
      } 
     } 
    } 
} 

if (self.superview.tag == noDisableHorizontalScrollTag) { 
    if (alpha == 0 && self.autoresizingMask == UIViewAutoresizingFlexibleTopMargin) { 
     if (self.frame.size.height < 10 && self.frame.size.height < self.frame.size.width) { 
      UIScrollView *sc = (UIScrollView*)self.superview; 
      if (sc.frame.size.width < sc.contentSize.width) { 
       return; 
      } 
     } 
    } 
} 

[super setAlpha:alpha]; 
} 
@end 

UPDATE: Это причина решения некоторые проблемы на 64-битной. Более подробно смотрите here

+0

Я не мог заставить это работать, и я также не совсем понимаю, что он должен делать. Почему мы устанавливаемAlpha в свитке, когда пытаемся show scrollbars. Не могли бы вы немного объяснить концепцию здесь? –

+2

Это не очень хороший ответ, это категория, которая переопределяет каждый метод 'UIImageView' setAlpha'. Он полагается на индикаторы прокрутки, имеющие определенный номер тега , который является частной деталью реализации и может быть изменен. – lxt

+1

Это похоже на основную причину http://stackoverflow.com/a/20944188/123269 - что приводит к ошибке UI при работе в 64-битном режиме. против использования этого кода. –

3

Это один работал для меня:

#define noDisableVerticalScrollTag 836913 
#define noDisableHorizontalScrollTag 836914 

@implementation UIImageView (ForScrollView) 

- (void) setAlpha:(float)alpha { 

    if (self.superview.tag == noDisableVerticalScrollTag) { 
     if (alpha == 0 && self.autoresizingMask == UIViewAutoresizingFlexibleLeftMargin) { 
      if (self.frame.size.width < 10 && self.frame.size.height > self.frame.size.width) { 
       UIScrollView *sc = (UIScrollView*)self.superview; 
       if (sc.frame.size.height < sc.contentSize.height) { 
        return; 
       } 
      } 
     } 
    } 

    if (self.superview.tag == noDisableHorizontalScrollTag) { 
     if (alpha == 0 && self.autoresizingMask == UIViewAutoresizingFlexibleTopMargin) { 
      if (self.frame.size.height < 10 && self.frame.size.height < self.frame.size.width) { 
       UIScrollView *sc = (UIScrollView*)self.superview; 
       if (sc.frame.size.width < sc.contentSize.width) { 
        return; 
       } 
      } 
     } 
    } 

    [super setAlpha:alpha]; 
} 
@end 

Я получил этот фрагмент отсюда: http://www.developers-life.com/scrollview-with-scrolls-indicators-which-are-shown-all-the-time.html

+0

Пожалуйста, объясните, как это использовать? – Minakshi

+0

@Xyz Если вы все еще ищете объяснение, как к нам e этот код см. здесь: [Сделать панель прокрутки всегда видимой в UIScrollView?] (http://stackoverflow.com/questions/13697215/make-a-scrollbar-always-visible-in-xcode/15613852#15613852) –

+0

Большое спасибо Эллиот Перри. – Minakshi

0

IOS не предлагает API.Но если вы действительно хотите этого, вы можете добавить свой собственный индикатор прокрутки вида и макету его самостоятельно, так же, как демонстрационные делают:

 
- (void)layoutSubviews 
{ 
    [super layoutSubviews]; 

    if (self.showsVerticalScrollIndicatorAlways) { 
     scroll_indicator_position(self, k_scroll_indicator_vertical); 
    } 

    if (self.showsHorizontalScrollIndicatorAlways) { 
     scroll_indicator_position(self, k_scroll_indicator_horizontal); 
    } 
} 

Ссылка https://github.com/flexih/MazeScrollView

0

ScrollBar, который функционирует так же, как прошивка встроенный в одном, но вы можете возиться с цветом и шириной.

-(void)persistantScrollBar 
{ 
    [persistantScrollBar removeFromSuperview]; 
    [self.collectionView setNeedsLayout]; 
    [self.collectionView layoutIfNeeded]; 

    if (self.collectionView.contentSize.height > self.collectionView.frame.size.height + 10) 
    { 
     persistantScrollBar = [[UIView alloc] initWithFrame:(CGRectMake(self.view.frame.size.width - 10, self.collectionView.frame.origin.y, 5, (self.collectionView.frame.size.height /self.collectionView.contentSize.height) * self.collectionView.frame.size.height))]; 
     persistantScrollBar.backgroundColor = [UIColor colorWithRed:207/255.f green:207/255.f blue:207/255.f alpha:0.5f]; 
     persistantScrollBar.layer.cornerRadius = persistantScrollBar.frame.size.width/2; 
     persistantScrollBar.layer.zPosition = 0; 
     [self.view addSubview:persistantScrollBar]; 
    } 
} 

-(void)scrollViewDidScroll:(UIScrollView *)scrollView 
{ 
    CGRect rect = persistantScrollBar.frame; 
    rect.origin.y = scrollView.frame.origin.y + (scrollView.contentOffset.y *(self.collectionView.frame.size.height/self.collectionView.contentSize.height)); 
    rect.size.height = (self.collectionView.frame.size.height /self.collectionView.contentSize.height) * self.collectionView.frame.size.height; 
    if (scrollView.contentOffset.y <= 0) 
    { 
     rect.origin.y = scrollView.frame.origin.y; 
     rect.size.height = rect.size.height + (scrollView.contentOffset.y); 
    } 
    else if (scrollView.contentOffset.y + scrollView.frame.size.height >= scrollView.contentSize.height) 
    { 
     rect.size.height = rect.size.height - ((scrollView.contentOffset.y + scrollView.frame.size.height) - scrollView.contentSize.height); 
     rect.origin.y = (self.collectionView.frame.origin.y + self.collectionView.frame.size.height - 5) - rect.size.height; 
    } 

    persistantScrollBar.frame = rect; 
} 
1

Я хочу предложить свое решение. Мне не нравится самый популярный вариант с категорией (переопределяющие методы в категории могут быть причиной некоторой неопределенности, какой метод следует вызывать во время выполнения, так как существует два метода с одним и тем же селектором). Вместо этого я использую swizzling. А также мне не нужно использовать теги.

Добавить этот метод в ваш контроллер представления, где вы прокрутите вид (self.categoriesTableView свойство представляет собой вид таблицы, где я хочу, чтобы показать полосы прокрутки)

- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    // Do swizzling to turn scroll indicator always on 
    // Search correct subview with vertical scroll indicator image across tableView subviews 
    for (UIView * view in self.categoriesTableView.subviews) { 
     if ([view isKindOfClass:[UIImageView class]]) { 
      if (view.alpha == 0 && view.autoresizingMask == UIViewAutoresizingFlexibleLeftMargin) { 
       if (view.frame.size.width < 10 && view.frame.size.height > view.frame.size.width) { 
        if (self.categoriesTableView.frame.size.height < self.categoriesTableView.contentSize.height) { 
         // Swizzle class for found imageView, that should be scroll indicator 
         object_setClass(view, [AlwaysOpaqueImageView class]); 
         break; 
        } 
       } 
      } 
     } 
    } 
    // Search correct subview with horizontal scroll indicator image across tableView subviews 
    for (UIView * view in self.categoriesTableView.subviews) { 
     if ([view isKindOfClass:[UIImageView class]]) { 
      if (view.alpha == 0 && view.autoresizingMask == UIViewAutoresizingFlexibleTopMargin) { 
       if (view.frame.size.height < 10 && view.frame.size.height < view.frame.size.width) { 
        if (self.categoriesTableView.frame.size.width < self.categoriesTableView.contentSize.width) { 
         // Swizzle class for found imageView, that should be scroll indicator 
         object_setClass(view, [AlwaysOpaqueImageView class]); 
         break; 
        } 
       } 
      } 
     } 
    } 
    // Ask to flash indicator to turn it on 
    [self.categoriesTableView flashScrollIndicators]; 
} 

Добавить новый класс

@interface AlwaysOpaqueImageView : UIImageView 
@end 

@implementation AlwaysOpaqueImageView 

- (void)setAlpha:(CGFloat)alpha { 
    [super setAlpha:1.0]; 
} 

@end 

индикатор прокрутки (вертикальный индикатор прокрутки в начале for цикл и горизонтальный во втором цикле for) будет всегда на экране. Если вам нужен только один индикатор, оставите только этот код for и удалите еще один.

+0

Привет, Какие изменения мне нужны для горизонтального индикатора? – Asim

+0

@Asim, см. Мой обновленный ответ –

0

Swift 3

Вы можете получить доступ к скроллбар с помощью scrollView.subviews и изменять альфа, как показано здесь. Меня устраивает.

extension UIScrollView { 
    override open func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 
     for x in self.subviews { 
      x.alpha = 1.0 
     } 
    } 
} 

extension MyScrollViewDelegate : UIScrollViewDelegate { 
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { 
     for x in scrollView.subviews { 
      x.alpha = 1.0 
     } 
    } 
} 
Смежные вопросы