iOS开发之AVPlayer的精彩使用--->网易新闻视频播放界面的另类实现

遇到个需求需要涉及到视频播放,那么没办法,先找资料开始进一步了解下这个不熟悉的东西.一个是MP,一个

是AV,MP是封装好的,用起来非常简单,但是自定义样式就基本不可能了。AVPlayer存在于AVFundation中,更接近

于底层,所以灵活性更强大,废话不多说,咱们先简单写个Demo看下他的工作原理,然后模仿网易新闻写个界面出

来,这里用到了一个封装的框架,如果不熟悉内部原理的同学可以先看看我写的第一个Demo,基本所有逻辑都有。

这里容我啰嗦一句:

开发中,单纯的使用AVPlayer类是无法播放视频的,需要将视频层添加到AVPLayerLayer层,这样视频才能显示出

来,Layer的定义方式有两种,一种是下面这种直接使用PlayerLayer,还有一个就是自己做一个View,然后把他自身的Layer改成playerLayer

第一种方式:

self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
self.playerLayer.videoGravity     = AVLayerVideoGravityResizeAspect;
self.playerLayer.frame = self.view.bounds;
[self.view.layer addSublayer:self.playerLayer];

第二种方式:

//修改当前view的 layer的 class
+(Class)layerClass
{
    //AVPlayerLayer
    return [AVPlayerLayer class];
}

不BB了,直接看图说话,先看看最终的效果图   

      

只能上传2M的东东,这视频一帧一帧消耗太快了,都不敢多录了,各位大爷将就着看吧。。。。。。

不要来打我,不然我让我表哥打死你     

先简单介绍下AVPlayer的用法

很多朋友应该和我一样,一开始接触视频的时候都不知道用什么东东来写,如果是大神

就直接下载Demo吧。小白来介绍下,我也第一次用

第一:初始化播放器

// 初始化播放器item
    self.playerItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:@"http://flv2.bn.netease.com/videolib3/1608/30/zPuaL7429/SD/zPuaL7429-mobile.mp4"]];
    self.player = [[AVPlayer alloc] initWithPlayerItem:self.playerItem];
    // 初始化播放器的Layer
    self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
    // layer的frame
    self.playerLayer.frame = self.backView.bounds;
    // layer的填充属性 和UIImageView的填充属性类似
    // AVLayerVideoGravityResizeAspect 等比例拉伸,会留白
    // AVLayerVideoGravityResizeAspectFill // 等比例拉伸,会裁剪
    // AVLayerVideoGravityResize // 保持原有大小拉伸
    self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    // 把Layer加到底部View上
    [self.backView.layer insertSublayer:self.playerLayer atIndex:0];

第二:给播放器加监听以及屏幕旋转的通知

// 监听播放器状态变化
    [self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    // 监听缓存进去,就是大家所看到的一开始进去底部灰色的View会迅速加载
    [self.playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];

    //旋转屏幕通知
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(onDeviceOrientationChange)
                                                 name:UIDeviceOrientationDidChangeNotification
                                               object:nil
     ];

第三步:实现KVO的监听方法

// 监听播放器的变化属性
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"status"])
    {
         AVPlayerItemStatus statues = [change[NSKeyValueChangeNewKey] integerValue];
        switch (statues) {
                // 监听到这个属性的时候,理论上视频就可以进行播放了
            case AVPlayerItemStatusReadyToPlay:

                // 最大值直接用sec,以前都是
                // CMTimeMake(帧数(slider.value * timeScale), 帧/sec)
                self.slider.maximumValue = CMTimeGetSeconds(self.playerItem.duration);
                [self initTimer];
                // 启动定时器 5秒自动隐藏
                if (!self.autoDismissTimer)
                {
                    self.autoDismissTimer = [NSTimer timerWithTimeInterval:8.0 target:self selector:@selector(autoDismissView:) userInfo:nil repeats:YES];
                    [[NSRunLoop currentRunLoop] addTimer:self.autoDismissTimer forMode:NSDefaultRunLoopMode];
                }
                break;

            case AVPlayerItemStatusUnknown:

                break;
                // 这个就是不能播放喽,加载失败了
            case AVPlayerItemStatusFailed:

                // 这时可以通过`self.player.error.description`属性来找出具体的原因

                break;

            default:
                break;
        }
    }
    else if ([keyPath isEqualToString:@"loadedTimeRanges"]) // 监听缓存进度的属性
    {
        // 计算缓存进度
        NSTimeInterval timeInterval = [self availableDuration];
        // 获取总长度
        CMTime duration = self.playerItem.duration;

        CGFloat durationTime = CMTimeGetSeconds(duration);
        // 监听到了给进度条赋值
        [self.progressView setProgress:timeInterval / durationTime animated:NO];
    }
}

AVPlayerItemStatusReadyToPlay

AVPlayerItemStatusFailed

这两个属性还比较好理解,是个人都知道,但是这个是什么鬼

AVPlayerItemStatusUnknown

内部是这么解释的

Indicates that the status of the player item is not yet known because it has not tried to load new media resources

for playback.

fk u 我英语不好,看不懂啊,估计是playerItem这个视频资源对象挂了,识别不了,暂时不知道怎么处理

      

第四步:调用Play&#8;er的方法观察时间变化&#8;更新播放进度

来个官方的说话,显得我比较牛B

// 调用plaer的对象进行UI更新
- (void)initTimer
{
    // player的定时器
    __weak typeof(self)weakSelf = self;
    // 每秒更新一次UI Slider
    [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {

        // 当前时间
        CGFloat nowTime = CMTimeGetSeconds(weakSelf.playerItem.currentTime);
        // 总时间
        CGFloat duration = CMTimeGetSeconds(weakSelf.playerItem.duration);
        // sec 转换成时间点
        weakSelf.nowLabel.text = [weakSelf convertToTime:nowTime];
        weakSelf.remainLabel.text = [weakSelf convertToTime:(duration - nowTime)];

        // 不是拖拽中的话更新UI
        if (!weakSelf.isDragSlider)
        {
            weakSelf.slider.value = CMTimeGetSeconds(weakSelf.playerItem.currentTime);
        }

    }];
}
// sec 转换成指定的格式
- (NSString *)convertToTime:(CGFloat)time
{
    // 初始化格式对象
    NSDateFormatter *fotmmatter = [[NSDateFormatter alloc] init];
    // 根据是否大于1H,进行格式赋值
    if (time >= 3600)
    {
        [fotmmatter setDateFormat:@"HH:mm:ss"];
    }
    else
    {
        [fotmmatter setDateFormat:@"mm:ss"];
    }
    // 秒数转换成NSDate类型
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:time];
    // date转字符串
    return [fotmmatter stringFromDate:date];
}

第五步:给背景View加个手势,点击的时候让title和时间进度条消失或者几秒钟自动消失

// 启动定时器 5秒自动隐藏
                // 咱们这种初始化定时器的方式需要自己手动加到runloop上
                // scheduledTimerWithTimeInterval用这个的时候就不需要手动加到runloop中
                if (!self.autoDismissTimer)
                {
                    self.autoDismissTimer = [NSTimer timerWithTimeInterval:8.0 target:self selector:@selector(autoDismissView:) userInfo:nil repeats:YES];
                    [[NSRunLoop currentRunLoop] addTimer:self.autoDismissTimer forMode:NSDefaultRunLoopMode];
                }
#pragma mark - 自动隐藏bottom和top
- (void)autoDismissView:(NSTimer *)timer
{
    // player的属性rate
    /* indicates the current rate of playback; 0.0 means "stopped", 1.0 means "play at the natural rate of the current item" */
    if (self.player.rate == 0)
    {
        // 暂停状态就不隐藏
    }
    else if (self.player.rate == 1)
    {
        if (self.bottomView.alpha == 1)
        {
            [UIView animateWithDuration:1.0 animations:^{

                self.bottomView.alpha = 0;
                self.topView.alpha = 0;

            }];
        }
    }
}

第六步:来个全屏小屏幕切换示例

其实切换的时候就是把只之前的Layer移除,然后重新布局,加到KeyWindow中去

// 全屏显示
-(void)toFullScreenWithInterfaceOrientation:(UIInterfaceOrientation )interfaceOrientation{
    // 先移除之前的
    [self.backView removeFromSuperview];
    // 初始化
    self.backView.transform = CGAffineTransformIdentity;
    if (interfaceOrientation==UIInterfaceOrientationLandscapeLeft) {
        self.backView.transform = CGAffineTransformMakeRotation(-M_PI_2);
    }else if(interfaceOrientation==UIInterfaceOrientationLandscapeRight){
        self.backView.transform = CGAffineTransformMakeRotation(M_PI_2);
    }
    // BackView的frame能全屏
    self.backView.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight);
    // layer的方向宽和高对调
    self.playerLayer.frame = CGRectMake(0, 0, kScreenHeight, kScreenWidth);

    // remark 约束
    [self.bottomView mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.height.mas_equalTo(50);
        make.top.mas_equalTo(kScreenWidth-50);
        make.left.equalTo(self.backView).with.offset(0);
        make.width.mas_equalTo(kScreenHeight);
    }];

    [self.topView mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.height.mas_equalTo(50);
        make.left.equalTo(self.backView).with.offset(0);
        make.width.mas_equalTo(kScreenHeight);
    }];

    [self.closeButton mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.backView).with.offset(5);
        make.height.mas_equalTo(30);
        make.width.mas_equalTo(30);
        make.top.equalTo(self.backView).with.offset(10);

    }];

    [self.titleLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.topView).with.offset(45);
        make.right.equalTo(self.topView).with.offset(-45);
        make.center.equalTo(self.topView);
        make.top.equalTo(self.topView).with.offset(0);
    }];

    [self.nowLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.slider.mas_left).with.offset(0);
        make.top.equalTo(self.slider.mas_bottom).with.offset(0);
        make.size.mas_equalTo(CGSizeMake(100, 20));
    }];

    [self.remainLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(self.slider.mas_right).with.offset(0);
        make.top.equalTo(self.slider.mas_bottom).with.offset(0);
        make.size.mas_equalTo(CGSizeMake(100, 20));
    }];
    // 加到window上面
    [[UIApplication sharedApplication].keyWindow addSubview:self.backView];
}

// 缩小到cell
-(void)toCell{
    // 先移除
    [self.backView removeFromSuperview];

    __weak typeof(self)weakSelf = self;
    [UIView animateWithDuration:0.5f animations:^{
        weakSelf.backView.transform = CGAffineTransformIdentity;
        weakSelf.backView.frame = CGRectMake(0, 80, kScreenWidth, kScreenHeight / 2.5);
        weakSelf.playerLayer.frame =  weakSelf.backView.bounds;
        // 再添加到View上
        [weakSelf.view addSubview:weakSelf.backView];

        // remark约束
        [self.bottomView mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(weakSelf.backView).with.offset(0);
            make.right.equalTo(weakSelf.backView).with.offset(0);
            make.height.mas_equalTo(50);
            make.bottom.equalTo(weakSelf.backView).with.offset(0);
        }];
        [self.topView mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(weakSelf.backView).with.offset(0);
            make.right.equalTo(weakSelf.backView).with.offset(0);
            make.height.mas_equalTo(50);
            make.top.equalTo(weakSelf.backView).with.offset(0);
        }];

        [self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(weakSelf.backView).with.offset(5);
            make.centerY.equalTo(weakSelf.topView);
            make.size.mas_equalTo(CGSizeMake(30, 30));
        }];
    }completion:^(BOOL finished) {

    }];
}

基本逻辑差不多介绍完了,效果就这样的

  

下面咱们试着写个网易播放视频的Demo,在tableView中使用下,效果图已经在最上面了

这里无非多了几个属性

@property (nonatomic,strong)
NSIndexPath *currentIndexPath;
// 当前播放的cell

@property (nonatomic,assign)
BOOL isSmallScreen; //
是否放置在window上

@property(nonatomic,strong)
ViedoTableViewCell *currentCell;
// 当前cell

分析1:全屏小屏切换的时候回到指定的cell,那么先点击播放记录位置

1.第一种cell播放:Layer是加载到cell上的背景图片区域的 滚动的时候要记录当前cell

2.第二种全屏播放:Layer是加载到Window上的 frame全屏

3.第三种小窗播放:它其实就是全屏播放的一个特例,也是加载到Window上的,frame自定义

其实不同状态的切换无非就是Layer所在View的位置不停切换

下面这个方法就是记录当前播放的cell下标

#pragma mark - 播放器播放

- (void)startPlayVideo:(UIButton *)sender
{
    // 获取当前的indexpath
    self.currentIndexPath = [NSIndexPath indexPathForRow:sender.tag inSection:0];

    // iOS 7 和 8 以上获取cell的方式不同
    if ([UIDevice currentDevice].systemVersion.floatValue>=8||[UIDevice currentDevice].systemVersion.floatValue<7) {
        self.currentCell = (ViedoTableViewCell *)sender.superview.superview;
    }else{//ios7系统 UITableViewCell上多了一个层级UITableViewCellScrollView
        self.currentCell = (ViedoTableViewCell *)sender.superview.superview.subviews;
    }
    ViedoModel *model = [self.viedoLists objectAtIndex:sender.tag];

    // 小窗口的时候点击播放另一个 先移除掉
    if (self.isSmallScreen) {
        [self releaseWMPlayer];
        self.isSmallScreen = NO;

    }
    // 当有上一个在播放的时候 点击 就先release
    if (self.wmPlayer) {
        [self releaseWMPlayer];
        self.wmPlayer = [[WMPlayer alloc]initWithFrame:self.currentCell.mainImageView.bounds];
        self.wmPlayer.delegate = self;
        self.wmPlayer.closeBtnStyle = CloseBtnStyleClose;
        self.wmPlayer.URLString = model.mp4URL;
        self.wmPlayer.titleLabel.text = model.title;
        //        [wmPlayer play];
    }else{
        // 当没有一个在播放的时候
        self.wmPlayer = [[WMPlayer alloc]initWithFrame:self.currentCell.mainImageView.bounds];
        self.wmPlayer.delegate = self;
        self.wmPlayer.closeBtnStyle = CloseBtnStyleClose;
        self.wmPlayer.titleLabel.text = model.title;
        self.wmPlayer.URLString = model.mp4URL;
    }
    // 把播放器加到当前cell的imageView上面
    [self.currentCell.mainImageView addSubview:self.wmPlayer];
    [self.currentCell.mainImageView bringSubviewToFront:self.wmPlayer];
    [self.currentCell.playButton.superview sendSubviewToBack:self.currentCell.playButton];
    [self.tableView reloadData];
}

分析2:上下滚动的时候根据坐标切换cell显示还是小窗显示

#pragma mark scrollView delegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if(scrollView ==self.tableView){
        if (self.wmPlayer==nil) {
            return;
        }

        if (self.wmPlayer.superview) {
            // 当前cell在tableView中的frame
//            (lldb) po rectInTableView
//            (origin = (x = 0, y = 0), size = (width = 375, height = 300))
            CGRect rectInTableView = [self.tableView rectForRowAtIndexPath:self.currentIndexPath];
            // 把当前的frame从tableView转换到屏幕View上面去
//            (lldb) po rectInSuperview
//            (origin = (x = 0, y = 61), size = (width = 375, height = 300))
            CGRect rectInSuperview = [self.tableView convertRect:rectInTableView toView:[self.tableView superview]];
            NSLog(@"Y轴变化:%lf,currentCell:%lf",rectInSuperview.origin.y,self.currentCell.mainImageView.frame.size.height);
            // 当网上移出屏幕的时候或者往下移出屏幕的时候,根据逻辑是否加载到小窗上来
            if (rectInSuperview.origin.y<-self.currentCell.mainImageView.frame.size.height ||rectInSuperview.origin.y>kScreenHeight-kNavbarHeight-kTabBarHeight) {//往上拖动
                // 如果已经小屏幕显示了,就不做任何操作
                if ([[UIApplication sharedApplication].keyWindow.subviews containsObject:self.wmPlayer]&&self.isSmallScreen) {
                    self.isSmallScreen = YES;
                }else{
                    //放widow上,小屏显示 这里的逻辑和展示到全屏是一样的道理,只是位置和frame自己定义就好了,想放哪就放哪
                    [self toSmallScreen];
                }

            }else{
                // 如果已经在cell里面了,那么就不做任何操作
                if ([self.currentCell.mainImageView.subviews containsObject:self.wmPlayer]) {

                }else{
                    // 如果进入屏幕,而且未在cell上,那么动画回currentCell
                    [self toCell];
                }
            }
        }

    }
}
// 滚动的时候小屏幕,放window上显示
-(void)toSmallScreen{
    //放widow上
    [self.wmPlayer removeFromSuperview];
    __weak typeof(self)weakSelf = self;
    [UIView animateWithDuration:0.5f animations:^{
       weakSelf.wmPlayer.transform = CGAffineTransformIdentity;
        // 设置window上的位置
        weakSelf.wmPlayer.frame = CGRectMake(kScreenWidth/2,kScreenHeight-kTabBarHeight + 40 -(kScreenWidth/2)*0.75, kScreenWidth/2, (kScreenWidth/2)*0.75);
        weakSelf.wmPlayer.playerLayer.frame =  weakSelf.wmPlayer.bounds;
        // 下面就是更新布局的代码,此处省略了,需要的去下载Demo看看

分析3:用MJRefresh做个JD的加载动画(随便做的,大家随便感受下)

&#8;

MKJRefreshHeader * header = [MKJRefreshHeader headerWithRefreshingTarget:self refreshingAction:@selector(refreshData)];
    header.stateLabel.hidden = YES;
    header.lastUpdatedTimeLabel.hidden = YES;
    header.mj_h = 80;
    self.tableView.mj_header = header;

   
这是JD的加载动画View以及重写的MJHeader文件

这里简单的写个重写的方法示例,具体需要看的大家去下载Demo

- (void)setState:(MJRefreshState)state
{
    MJRefreshCheckState
    // 根据状态做事情
    // 刷新完毕
    if (state == MJRefreshStateIdle) {
        if (oldState == MJRefreshStateRefreshing) {
            self.arrowView.transform = CGAffineTransformIdentity;

            [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{
                self.loadingView1.alpha = 0.0;
            } completion:^(BOOL finished) {
                // 如果执行完动画发现不是idle状态,就直接返回,进入其他状态
                if (self.state != MJRefreshStateIdle) return;

                self.loadingView1.alpha = 1.0;
                [self.loadingView1 endRefresing];
                self.arrowView.hidden = NO;
            }];
        } else { // 拉倒即将刷新的时候,又往回缩,不进行刷新
            [self.loadingView1 endRefresingDown];
            self.arrowView.hidden = NO;
            [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{
                self.arrowView.transform = CGAffineTransformIdentity;
            }];
        }
    } else if (state == MJRefreshStatePulling) { // 继续往下拉的时候
        [self.loadingView1 refreing];
        NSLog(@"连接点");
        self.arrowView.hidden = NO;
        [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{
            self.arrowView.transform = CGAffineTransformMakeRotation(0.000001 - M_PI);
        }];
    } else if (state == MJRefreshStateRefreshing) { // 刷新
        self.loadingView1.alpha = 1.0; // 防止refreshing -> idle的动画完毕动作没有被执行
        [self.loadingView1 refreing];
        self.arrowView.hidden = YES;
    }
}

尼玛啊,一口气写了那么多,语文水平还没及格的我真的&#8;感觉身体被掏空了

篇幅有点多了,感觉没必要什么都写出来,需要的同学去研究下Demo吧,感谢看到这

里的小伙伴,你们都是好人,好人一生平安啊,要不再点个赞???!!!

简单Demo示例地址:点击打开简单Demo链接

&#8;类似网易视频播放最终Demo地址:点击打开网易Demo链接

小白写的东东,希望能帮到大家,大神的话可以给点意见,有问题留言哦

时间: 2024-10-10 17:59:39

iOS开发之AVPlayer的精彩使用--->网易新闻视频播放界面的另类实现的相关文章

李洪强iOS开发之iOS好文章收集

李洪强iOS开发之iOS好文章收集 该文收集朋友们转发或自己的写的技术文章,如果你也有相关的好文章,欢迎留言,当好文章多的时候,我会对这些好文章进行分门别类 文章 简述 日期 直播服务配置 使用 nginx 和 rtmp 插件搭建视频直播和点播服务器 2015-05-12 20:13:00 iOS9适配技巧 图iOS9适配新技巧 2015-09-29 09:01 TextKit分页效果 图文混排 2015年6月1日 iPhone 6 / 6 Plus 设计·适配方案 屏幕适配 2014-11-2

iOS开发之 Method Swizzling 深入浅出

<p align="center"><img src ="https://raw.githubusercontent.com/DotzuX/Notes/master/logo.jpeg"/></p> iOS开发之 Method Swizzling 深入浅出 只要善用Google,网上有很多关于Method Swizzling的Demo,在这里我就不打算贴代码了,主要介绍下概念,原理,注意事项等等. 开发需求 如果产品经理突然说:&

IOS开发之copy的问题

copy的目的就是修改副本,修改原始对象和副本时不会产生干扰. 定义一个不可变属性A,再定义一个可变属性B.用B做添加删除等操作后再将B赋值给A时,有些人习惯用A = B:其实这样是不安全的. 假设有下面的一段代码: ? 1 2 3 4 5 6 7 8 9 10   int main() {    NSMutableString *strM = [NSMutableString [email protected]"123"];    NSString *str = strM;    N

iOS开发之WKWebView简单使用和常用使用场景

iOS开发之 WKWebVeiw使用 想用UIWebVeiw做的,但是突然想起来在iOS8中出了一个新的WKWebView,算是UIWebVeiw的升级版.本着对新事物的好奇,就上网查了一下,但是找了好多个都没说的多了详细,于是就问谷歌,找文档,看看使用方法,试用了一下,果然不错,记录下来,大家分享! WKWebView的特点: 性能高,稳定性好,占用的内存比较小, 支持JS交互 支持HTML5 新特性 可以添加进度条(然并卵,不好用,还是习惯第三方的). 支持内建手势, 据说高达60fps的刷

iOS开发之Auto Layout入门

随着iPhone6与iOS8的临近,适配的问题讲更加复杂,最近学习了一下Auto Layout的使用,与大家分享.  什么是Auto Layout? Auto Layout是iOS6发布后引入的一个全新的布局特性,其目的是弥补以往Autoresizing在布局方面的不足之处,以及未来面对更多尺寸适配时界面布局可以更好的适应. 为什么要用Auto Layout? Autolayout能解决不同屏幕(iPhone4,iPhone5,iPad...)之间的适配问题. 在iPhone4时代开发者只需要适

iOS开发之CocoaPods的使用

透明色:00ff00ff //设置柱状图的颜色                ColorSet cs = new ColorSet();                cs.Id = "colorset1"; #region 设置柱状图的颜色 待开发                    string strColor = oYAXIS.Color;                    switch (strColor)                    {           

iOS开发之UILabel

UILabel是iOS开发中常用的一个组件,主要用来显示内容. UILabel的主要使用如下: ? 1 2 3 4 5 6 7 8 9 10 /*尺寸*/ CGRect labelRect = CGRectMake(100, 100, 80, 40); /*初始化*/ UILabel *titleLabel = [[UILabel alloc] initWithFrame:labelRect]; /*一些属性的设置*/ titleLabel.font = [UIFont systemFontOf

iOS开发之多XIB之间相互关联

Xib link Xib 1.直接加载xib中的UIView 创建一个View1.xib, 随便设一个背景色,加一个标识UILabel, 这样好知道是这个view是哪一个view. 你可以在这个view上加作意的subview,我只是说明原理,所以这儿并没有加作何subview. 最终我的View1如下图: 由于View1会放到其它View上作为subview,所以这儿size是Freeform, Status Bar是:None. 将下面代码放到viewDidLoad中: &1这行代码就是加载

iOS开发之UISearchBar初探

iOS开发之UISearchBar初探 UISearchBar也是iOS开发常用控件之一,点进去看看里面的属性barStyle.text.placeholder等等.但是这些属性显然不足矣满足我们的开发需求.比如:修改placeholder的颜色.修改UISearchBar上面的UITextfield的背景颜色.修改UITextfield上面的照片等等. 为了实现上述的需求,最好写一个UISearchBar的子类就叫LSSearchBar吧 LSSearchBar.h如下: #import <U