iOS开发系列课程(09) — 滚动视图详解手机开发

UIScrollView入门

  移动设备的屏幕⼤小是极其有限的,因此直接展⽰在⽤户眼前的内容也相当有限,当展⽰的内容较多超出一个屏幕时,用户可通过滚动操作来查看屏幕以外的内容,普通的UIView不具备滚动功能,不能显⽰过多的内容。UIScrollView是一个能够滚动的视图控件,可以⽤用来展⽰大量的内容,并且可以通过滚动查看所有的内容。

  UIScollView的常用属性和方法:
– contentOffset属性:UIScrollView滚动的位置
– contentSize属性:UIScrollView内容的尺⼨寸(相当于滚动的范围)
– bounces属性:设置UIScrollView是否需要弹簧效果
– alwaysBounceVertical属性:设置垂直方向是否有弹簧效果(必须在bounces设置为YES的前提下设置才有效)
– alwaysBounceHorizontal属性:设置水平方向是否有弹簧效果(必须在bounces设置为YES的前提下设置才有效)
– pagingEnabled属性:设置UIScrollView的滚动方式是否为翻页效果
– scrollEnabled属性:设置UIScrollView是否能滚动
– showsHorizontalScrollIndicator属性:是否显示水平方向的滑动条
– showsVerticalScrollIndicator属性:是否显示垂直方向的滑动条
– scrollIndicatorInsets属性:设置滚动条的位置,可以通过UIEdgeInsetsMake函数来指定该位置
– indicatorStyle属性:设置滚动条的风格,有三个可选项:UIScrollViewIndicatorStyleDefault(灰)、UIScrollViewIndicatorStyleBlack(黑)、UIScrollViewIndicatorStyleWhite(白)
– decelerationRate属性:减速的速率
– scrollsToTop属性:设置点击状态栏是否滑动到scrollView的顶部
– -setContentOffset:animated:方法:设置scrollView的位置
– -scrollRectToVisible:animated:方法:将指定的区域滚动到可视范围之内,如果该地区已经在可视区域,则什么都不做。

  下面的例子演示了如何显示一张比屏幕尺寸大的图片,同时演示了如何定制滚动条以及如何通过Tap手势将点击的位置移到靠近屏幕中心的位置,还演示了利用UIScrollView来实现缩放功能。

#import "ViewController.h" 
 
@interface ViewController () <UIScrollViewDelegate> { 
    UIScrollView *myScrollView; 
} 
 
@end 
 
@implementation ViewController 
 
- (void)viewDidLoad { 
    [super viewDidLoad]; 
 
    UIImage *image = [UIImage imageNamed:@"1092.jpg"]; 
    CGSize imageSize = image.size; 
 
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, imageSize.width, imageSize.height)]; 
    imageView.image = image; 
 
    // 创建一个滚动视图对象 
    myScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)]; 
 
    // 设置不允许拖拽滚动(通过Tap手势移动) 
    myScrollView.scrollEnabled = NO; 
    // 设置滚动视图中内容的尺寸 
    myScrollView.contentSize = image.size; 
    // 设置关闭滚动视图的弹簧效果 
    myScrollView.bounces = NO; 
    // 定制滚动条的样式 
    myScrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite; 
    // 定制滚动条的位置 
    myScrollView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 80, 40); 
    // 设置滚动条减速的速率(值越大减速越缓慢) 
    myScrollView.decelerationRate = 0.5; 
    // 隐藏掉水平和垂直滚动条 
    myScrollView.showsHorizontalScrollIndicator = NO; 
    myScrollView.showsVerticalScrollIndicator = NO; 
    // 不允许点状态栏回到视图顶部 
    myScrollView.scrollsToTop = NO; 
    // 绑定委托 
    myScrollView.delegate = self; 
    // 设置缩放比例 
    myScrollView.minimumZoomScale = 0.5; 
    myScrollView.maximumZoomScale = 2; 
 
 
    // 将UIImageView放到滚动视图上 
    [myScrollView addSubview:imageView]; 
    [self.view addSubview:myScrollView]; 
 
    CGSize screenSize = [UIScreen mainScreen].bounds.size; 
    // 用一个视图作为自定义滚动条 
    UIView *myScrollBar = [[UIView alloc] initWithFrame:CGRectMake(screenSize.width - 30, 0, 30, 40)]; 
    for (int i = 0; i < 3; i++) { 
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(5, 15 + 5 * i, 20, 2)]; 
        label.backgroundColor = [UIColor whiteColor]; 
        [myScrollBar addSubview:label]; 
    } 
    myScrollBar.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.7]; 
    [self.view addSubview:myScrollBar]; 
 
    // 给自定义的滚动条添加一个拖拽手势 
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(doScroll:)]; 
    [myScrollBar addGestureRecognizer:pan]; 
 
    // 添加一个Tap手势将连续两次点击屏幕的位置置于靠近屏幕中心的地方 
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(gotoThePoint:)]; 
    tap.numberOfTapsRequired = 2; 
    imageView.userInteractionEnabled = YES; 
    [imageView addGestureRecognizer:tap]; 
} 
 
// 拖拽手势的回调方法 
- (void) doScroll:(UIPanGestureRecognizer *) sender { 
    CGPoint point = [sender translationInView:self.view]; 
    CGPoint center = sender.view.center; 
    sender.view.center = CGPointMake(center.x, center.y + point.y); 
    CGPoint offsetPoint = myScrollView.contentOffset; 
    // 按照目前的设置地图的移动比例约为自定义滚动条移动比例的7.5倍 
    offsetPoint.y += point.y * 7.5; 
    // 判断滚动视图的offsetContent有否超出边界 
    if (offsetPoint.y < 0) { 
        offsetPoint.y = 0; 
    } 
    else if (offsetPoint.y > myScrollView.contentSize.height - self.view.bounds.size.height) { 
        offsetPoint.y = myScrollView.contentSize.height - self.view.bounds.size.height; 
    } 
    myScrollView.contentOffset = offsetPoint; 
    // 防止效果叠加(旋转、伸缩和拖拽的手势都需要还原来防止效果叠加) 
    [sender setTranslation:CGPointMake(0, 0) inView:self.view]; 
} 
 
- (void) gotoThePoint:(UITapGestureRecognizer *) sender { 
    CGSize screenSize = self.view.bounds.size; 
    CGPoint touchPoint = [sender locationInView:self.view]; 
    // 计算出点击的位置和屏幕中心点的差值 
    CGFloat dx = touchPoint.x - screenSize.width / 2; 
    CGFloat dy = touchPoint.y - screenSize.height / 2; 
    // 让滚动视图的偏移点的坐标加上坐标偏移量的值 
    CGPoint offsetPoint = myScrollView.contentOffset; 
    offsetPoint.x += dx; 
    offsetPoint.y += dy; 
    // 保证水平方向不会超出地图的边界 
    if (offsetPoint.x < 0) { 
        offsetPoint.x = 0; 
    } 
    else if (offsetPoint.x > myScrollView.contentSize.width - screenSize.width) { 
        offsetPoint.x = myScrollView.contentSize.width - screenSize.width; 
    } 
    // 保证垂直方向不会超出地图的边界 
    if (offsetPoint.y < 0) { 
        offsetPoint.y = 0; 
    } 
    else if (offsetPoint.y > myScrollView.contentSize.height - screenSize.height) { 
        offsetPoint.y = myScrollView.contentSize.height - screenSize.height; 
    } 
 
    [myScrollView setContentOffset:offsetPoint animated:YES]; 
} 
 
#pragma mark 滚动视图的回调方法 
 
// 通过滚动视图缩放其子视图的回调方法 
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)_scrollView { 
    return myScrollView.subviews[0]; 
}

  程序运行效果如下图所示:

这里写图片描述

UIScrollViewDelegate

  UIScrollViewDelegate协议定义了滚动视图对应的事件的回调方法,下面的代码展示了其中的一部分方法。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView { 
    NSLog(@"滚动") ; 
} 
 
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { 
    NSLog(@"将要开始拖拽") ; 
} 
 
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset { 
    NSLog(@"将要停止拖拽") ; 
} 
 
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { 
    NSLog(@"已经停止拖拽") ; 
} 
 
-(void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView { 
    NSLog(@"将要开始减速") ; 
} 
 
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 
    NSLog(@"已经停止减速") ; 
} 
 
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView { 
    NSLog(@"允许点击状态栏滚动到顶部"); 
    return YES ; 
} 
 
- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView { 
    NSLog(@"滚动到顶部") ; 
}

UIPageControl的使用

  UIPageControl类提供指示当前显示的是多页面视图的第几页的一排小圆点。

  UIPageControl的常用属性:
– numberOfPages属性:设置页数
– currentPage属性:当前是页码
– hidesForSinglePage属性:如果设为YES,在只有一页的情况下隐藏表示页码的点
– defersCurrentPageDisplay属性:如果你希望直到有时间执行完你的操作之后,才更新当前指示器当前指示页,可以将该属性设为YES
– pageIndicatorTintColor属性:设表示页码的点的颜色
– currentPageIndicatorTintColor属性:设置当前页点的颜色

  UIPageControl的常用方法:
– -updateCurrentPageDisplay:方法:更新页码指示器到当前页

#import "ViewController.h" 
 
@interface ViewController () <UIScrollViewDelegate> { 
    UIScrollView *scrollView; 
    UIPageControl *pageControl; 
} 
 
@end 
 
@implementation ViewController 
 
- (void)viewDidLoad { 
    [super viewDidLoad]; 
 
    CGSize screenSize = [UIScreen mainScreen].bounds.size; 
 
    scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 20, screenSize.width, screenSize.height)]; 
    scrollView.bounces = NO; 
    scrollView.showsHorizontalScrollIndicator = NO; 
    scrollView.showsVerticalScrollIndicator = NO; 
    // 设置滚动视图启用翻页模式 
    scrollView.pagingEnabled = YES; 
    // 设置滚动视图内容的尺寸宽度是屏幕宽度的3倍 
    scrollView.contentSize = CGSizeMake(3 * screenSize.width, screenSize.height - 20); 
    // 给滚动视图设置委托 
    scrollView.delegate = self; 
 
    // 循环创建3个水平排列的UIImageView对象 
    // 屏幕的可见范围之内只能看到UIImageView 
    for (int i = 1; i <= 3; i++) { 
        UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg", i]]; 
        UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; 
        // 每个UIImageView的横坐标是在前一个的基础上加上屏幕的宽度 
        imageView.frame = CGRectMake((i - 1) * screenSize.width, 0, screenSize.width, screenSize.height - 20); 
        [scrollView addSubview:imageView]; 
    } 
 
    [self.view addSubview:scrollView]; 
 
    pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, screenSize.height - 40, screenSize.width, 40)]; 
    pageControl.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5]; 
    // 设置总共有多少页 
    pageControl.numberOfPages = 3; 
    // 设置选中页的指示器颜色 
//    pageControl.currentPageIndicatorTintColor = [UIColor purpleColor]; 
    // 设置页码指示器的颜色 
//    pageControl.pageIndicatorTintColor = [UIColor yellowColor]; 
 
    [self.view addSubview:pageControl]; 
 
} 
 
// 滚动时回调此方法计算滚动到第几页 
- (void)scrollViewDidScroll:(UIScrollView *)_scrollView { 
    pageControl.currentPage = (NSInteger)(scrollView.contentOffset.x / [UIScreen mainScreen].bounds.size.width); 
} 
 
@end

  运行效果如下图所示:

这里写图片描述 这里写图片描述

UITextView

  UITextView相当于是高级版本的UILabel和UITextField的合体。

  UITextView的常用属性:
– editable属性:设置UITextView能否编辑,如果不编辑就当做UILabel显示,可以设置自动识别电话号码、地址、邮箱,该属性默认为YES
– dataDetectorTypes属性:设置UITextView是否支持识别电话号码、地址、邮箱等内容
– inputView:当UITextView成为第一响应者时显示的输入视图
– inputAccessoryView:当UITextView成为第一响应者时显示的输入辅助视图,在inputView的上方

  下面的例子演示了如何使用UITextView以及如何进行数据侦测和拼写检查。

#import "ViewController.h" 
 
@interface ViewController () <UITextViewDelegate> { 
    UITextView *myTextView; 
} 
 
@end 
 
@implementation ViewController 
 
- (void)viewDidLoad { 
    [super viewDidLoad]; 
 
    myTextView = [[UITextView alloc] initWithFrame:CGRectMake(50, 100, 275, 250)]; 
    myTextView.editable = YES; 
    myTextView.dataDetectorTypes = UIDataDetectorTypeAll; 
    myTextView.text = @"姓名: 骆昊/n电话: 13812345678/n主页: http://blog.csdn.net/jackfrued/n地址: 成都市西源大道1899号/nQQ: 12345678/n"; 
    myTextView.font = [UIFont systemFontOfSize:18]; 
    myTextView.returnKeyType = UIReturnKeyDone; 
    // myTextView.scrollEnabled = NO; 
 
    myTextView.layer.borderWidth = 1; 
    myTextView.layer.borderColor = [UIColor blackColor].CGColor; 
    myTextView.layer.cornerRadius = 5; 
 
    myTextView.delegate = self; 
    [myTextView becomeFirstResponder]; 
    // myTextView.selectedRange = NSMakeRange(10, 20); 
 
    [self.view addSubview:myTextView]; 
 
    UIButton *addButton = [UIButton buttonWithType:UIButtonTypeSystem]; 
    addButton.frame = CGRectMake(150, 380, 75, 40); 
    [addButton setTitle:@"添加" forState: UIControlStateNormal]; 
    [addButton addTarget:self action:@selector(addButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; 
 
    [self.view addSubview:addButton]; 
 
    UITextChecker *checker = [[UITextChecker alloc] init]; 
    NSRange range = NSMakeRange(0, myTextView.text.length); 
    NSString *language = [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]; 
    // NSLog(@"%@", language); 
    NSRange errRange = [checker rangeOfMisspelledWordInString:myTextView.text range:range startingAt:0 wrap:NO language:language]; 
    if (errRange.location != NSNotFound) { 
        myTextView.selectedRange = errRange; 
    } 
} 
 
- (void)textViewDidEndEditing:(UITextView *)textView { 
    [textView resignFirstResponder]; 
} 
 
- (void) addButtonClicked:(UIButton *) sender { 
    myTextView.text = [myTextView.text stringByAppendingString:@"Hello, world!/n"]; 
    [myTextView scrollRangeToVisible:NSMakeRange(myTextView.text.length, 1)]; 
} 
 
@end

  UITextView退出键盘几种方式:

  1. 如果应用有导航条的,可以在导航条上面加多一个Done的按钮,用来退出键盘,当然要先实UITextViewDelegate
  2. 如果UITextView中不使用回车键,可以把回车键当做退出键盘的响应键
  3. 自定义其他加载键盘上面用来退出,比如在弹出的键盘上面加一个view来放置退出键盘的Done按钮
  4. 点击其他区域收起键盘

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/app/5323.html

(0)
上一篇 2021年7月16日 23:41
下一篇 2021年7月16日 23:41

相关推荐

发表回复

登录后才能评论