如何让UITextView默认显示滚动条

问题:当文字内容超过textview时,希望默认显示滚动条,UITextView继承自UIScrollView,滚动条自在滚动手势追踪的时候才会出现,怎样让滚动条一直显示呢?

通过UI堆栈可以看到,滚动视图是一个UIImageView,隐藏的时候alpha为0,所以可以通过category的方式重新实现UIImageView的setAlpha方法,当父视图为需要默认显示滚动条的视图时,始终设置图片的alpha为1

具体步骤:1、定义一个默认显示滚动条的子类MRATextView,继承自UITextView。tag赋特殊值、定义一个属性从外部接收滚动条的高度、重写flashScrollIndicators方法(可滚动时设置滚动视图alpha为1,并且调整frame)。

     2、使用分类来重写UIImageView的setAlpha和setFrame方法,保证alpha不会被设置为0,frame正常可见。

具体代码:

1、MRATextView

 // MRATextView.h

@interface MRATextView : UITextView
@property(nonatomic) CGFloat verticalScrollBarH;
@end

// MRATextView.m

#import "MRATextView.h"
#import "FBKVOController.h"
#import "UIImageView+MRAScrollView.h"
@implementation MRATextView
-(instancetype)init{
    self = [super init];
    if (self) {
        self.tag = 836913;
    }
    return self;
}

-(void)flashScrollIndicators{
    [super flashScrollIndicators];
    if (self.scrollEnabled) {
        [self showScrollBar];
    }
}

-(void)showScrollBar{
    for(UIView *img in [self subviews]){
        if ([img isKindOfClass:[UIImageView class]] && img.autoresizingMask == UIViewAutoresizingFlexibleLeftMargin){
            UIImageView *scollBar = (UIImageView *)img;
            CGRect frame = scollBar.frame;
            frame.origin.y = 0;
            [scollBar setFrame:frame];
            [scollBar setAlpha:1];
        }
    }
}
@end

  img.autoresizingMask == UIViewAutoresizingFlexibleLeftMargin保证拿到的视图是竖直方向的滚动条。

  2、UIImageView+MRAScrollView

       // UIImageView+MRAScrollView.h 

@interface UIImageView(MRAScrollView) @end

  // UIImageView+MRAScrollView.m

#import "UIImageView+MRAScrollView.h"
#import "MRATextView.h"

@implementation UIImageView(MRAScrollView)
- (void)setAlpha:(CGFloat)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];
}

-(void)setFrame:(CGRect)frame{
    MRATextView *superView = (MRATextView *)self.superview;
    if (superView.tag == noDisableVerticalScrollTag && superView.scrollEnabled) {
        if (self.frame.origin.y < 0) {
            frame.origin.y = 0;
        }
        frame.size.height = superView.verticalScrollBarH;
    }
    [super setFrame: frame];
}
@end

 使用时直接 

   _textView = [[MRATextView alloc]init];  即可。

低版本系统兼容问题:1、iOS8号不可滑动,且默认展示滚动条。

原因:1、iOS8中需要手动设置contentsize,否则contentSize为(0,0)。  

         2、iOS中UIScrollView的某些特性,会掠过setAlpha方法,直接设置_alpha为0,所以重写UIImageview的setAlpha不能起到拦截作用。

解决办法:1、设置textView内容时,手动设置一下contentSize。

               2、在didMoveToWindow方法中重新设置一下滚动条的alpha和frame,使之可见,代码可以加在didMoveToWindow方法中。

-(void)didMoveToWindow{
    [super didMoveToWindow];
    [_textView flashScrollIndicators];
}

  

posted @ 2018-04-25 17:00  一坨☁️  阅读(811)  评论(0编辑  收藏  举报