在上教程中,我们介绍了二级导航栏的开发,今天我们来讲解iOS开发中非常常用和重要的组件:“列表”,即UITableView。本节课程将会介绍横向滚动列表和竖向滚动列表,分别来实现二级栏目滑动切换和新闻内容列表的功能。

  • UITableView介绍
  • 横向滚动列表-二级栏目滑动切换
  • 新闻内容列表

UITableView介绍

在OC中,UITableView是用来展示列表数据的控件,基本使用方法是:
1.首先,Controller需要实现两个delegate ,分别是UITableViewDelegate 和UITableViewDataSource
2.然后 UITableView对象的 delegate要设置为 self。
3.实现这些delegate的一些方法,重写。

横向滚动列表-二级栏目滑动切换

1.新建横向滚动列表类LandscapeTableView

//LandscapeTableView.h
#import <UIKit/UIKit.h>
#import "LandscapeCell.h"@protocol LandscapeTableViewDelegate;
@protocol LandscapeTableViewDataSource;@interface LandscapeTableView : UIView <UIScrollViewDelegat\> {// 存储页面的滚动条容器UIScrollView                *_scrollView;// 单元格之间的间隔,缺省20CGFloat                     _gapBetweenCells;// 预先加载的单元格数,在可见单元格的两边预先加载不可见单元格的数目NSInteger                   _cellsToPreload;// 单元格总数NSInteger                   _cellCount;// 当前索引NSInteger                   _currentCellIndex;// 上次选择的单元格索引NSInteger                   _lastCellIndex;// 加载当前可见单元格左边的索引NSInteger                   _firstLoadedCellIndex;// 加载当前可见单元格右边的索引NSInteger                   _lastLoadedCellIndex;// 可重用单元格控件的集合NSMutableSet                *_recycledCells;// 当前可见单元格集合NSMutableSet                *_visibleCells;// 是否正在旋转BOOL                        _isRotationing;// 页面容器是否正在滑动BOOL                        _scrollViewIsMoving;// 回收站是否可用,是否将不用的页控件保存到_recycledCells集合中BOOL                        _recyclingEnabled;
}@property(nonatomic, assign) IBOutlet id<LandscapeTableViewDataSource>    dataSource;
@property(nonatomic, assign) IBOutlet id<LandscapeTableViewDelegate>      delegate;@property(nonatomic, assign) CGFloat    gapBetweenCells;
@property(nonatomic, assign) NSInteger  cellsToPreload;
@property(nonatomic, assign) NSInteger  cellCount;
@property(nonatomic, assign) NSInteger  currentCellIndex;// 重新加载数据
- (void)reloadData;
// 由索引获得单元格控件,如果该单元格还没有加载将返回nil
- (LandscapeCell *)cellForIndex:(NSUInteger)index;
// 返回可以重用的单元格控件,如果没有可重用的,返回nil
- (LandscapeCell *)dequeueReusableCell;@end@protocol LandscapeTableViewDataSource
@required
- (NSInteger)numberOfCellsInTableView:(LandscapeTableView *)tableView;
- (LandscapeCell *)cellInTableView:(LandscapeTableView *)tableView atIndex:(NSInteger)index;@end@protocol LandscapeTableViewDelegate
@optional
- (void)tableView:(LandscapeTableView *)tableView didChangeAtIndex:(NSInteger)index;
- (void)tableView:(LandscapeTableView *)tableView didSelectCellAtIndex:(NSInteger)index;// a good place to start and stop background processing
- (void)tableViewWillBeginMoving:(LandscapeTableView *)tableView;
- (void)tableViewDidEndMoving:(LandscapeTableView *)tableView;@end

#import "LandscapeTableView.h"@interface LandscapeTableView (LandscapeTableViewPrivate) <UIScrollViewDelegate>- (void)configureCells;
- (void)configureCell:(LandscapeCell *)cell forIndex:(NSInteger)index;- (void)recycleCell:(LandscapeCell *)cell;- (CGRect)frameForScrollView;
- (CGRect)frameForCellAtIndex:(NSUInteger)index;- (void)willBeginMoving;
- (void)didEndMoving;@end@implementation LandscapeTableView#pragma mark - Lifecycle methods- (void)addContentView
{_scrollView = [[UIScrollView alloc] initWithFrame:[self frameForScrollView]];_scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;_scrollView.pagingEnabled = YES;_scrollView.backgroundColor = [UIColor whiteColor];_scrollView.showsVerticalScrollIndicator = NO;_scrollView.showsHorizontalScrollIndicator = NO;_scrollView.bounces = YES;_scrollView.delegate = self;[self addSubview:_scrollView];
}- (void)internalInit
{_visibleCells = [[NSMutableSet alloc] init];_recycledCells = [[NSMutableSet alloc] init];_currentCellIndex = -1;_lastCellIndex = 0;_gapBetweenCells = 20.0f;_cellsToPreload = 1;_recyclingEnabled = YES;_firstLoadedCellIndex = _lastLoadedCellIndex = -1;self.clipsToBounds = YES;[self addContentView];
}- (id)initWithCoder:(NSCoder *)aDecoder {if ((self = [super initWithCoder:aDecoder])) {[self internalInit];}return self;
}- (id)initWithFrame:(CGRect)frame
{self = [super initWithFrame:frame];if (self) {[self internalInit];}return self;
}- (void)dealloc
{self.delegate = nil;self.dataSource = nil;
}- (void)layoutSubviews
{if (_isRotationing)return;CGRect oldFrame = _scrollView.frame;CGRect newFrame = [self frameForScrollView];if (!CGRectEqualToRect(oldFrame, newFrame)) {// Strangely enough, if we do this assignment every time without the above// check, bouncing will behave incorrectly._scrollView.frame = newFrame;}if (oldFrame.size.width != 0 && _scrollView.frame.size.width != oldFrame.size.width) {// rotation is in progress, don't do any adjustments just yet} else if (oldFrame.size.height != _scrollView.frame.size.height) {// some other height change (the initial change from 0 to some specific size,// or maybe an in-call status bar has appeared or disappeared)[self configureCells];}
}#pragma mark - Propertites methods- (void)setGapBetweenCells:(CGFloat)value
{_gapBetweenCells = value;[self setNeedsLayout];
}- (void)setPagesToPreload:(NSInteger)value
{_cellsToPreload = value;[self configureCells];
}- (void)setCurrentCellIndex:(NSInteger)newCellIndex
{if (_scrollView.frame.size.width > 0 && fabs(_scrollView.frame.origin.x - (-_gapBetweenCells/2)) < 1e-6) {_scrollView.contentOffset = CGPointMake(_scrollView.frame.size.width * newCellIndex, 0);}_currentCellIndex = newCellIndex;_lastCellIndex = _currentCellIndex;
}- (NSInteger)firstVisibleCellIndex
{CGRect visibleBounds = _scrollView.bounds;return MAX(floorf(CGRectGetMinX(visibleBounds) / CGRectGetWidth(visibleBounds)), 0);
}- (NSInteger)lastVisibleCellIndex
{CGRect visibleBounds = _scrollView.bounds;return MIN(floorf((CGRectGetMaxX(visibleBounds)-1) / CGRectGetWidth(visibleBounds)), _cellCount - 1);
}#pragma mark - Utility methods- (void)reloadData
{_cellCount = [_dataSource numberOfCellsInTableView:self];// recycle all cellsfor (LandscapeCell *cell in _visibleCells) {[self recycleCell:cell];}[_visibleCells removeAllObjects];[self configureCells];
}- (LandscapeCell *)cellForIndex:(NSUInteger)index
{for (LandscapeCell *cell in _visibleCells) {if (cell.tag == index)return cell;}return nil;
}- (LandscapeCell *)dequeueReusableCell
{LandscapeCell *result = [_recycledCells anyObject];if (result) {[_recycledCells removeObject:result];}return result;
}#pragma mark - FZPageViewPrivate methods- (void)configureCells
{if (_scrollView.frame.size.width <= _gapBetweenCells + 1e-6)return;  // not our time yetif (_cellCount == 0 && _currentCellIndex > 0)return;  // still not our time// normally layoutSubviews won't even call us, but protect against any other calls too (e.g. if someones does reloadPages)if (_isRotationing)return;// to avoid hiccups while scrolling, do not preload invisible pages temporarilyBOOL quickMode = (_scrollViewIsMoving && _cellsToPreload > 0);CGSize contentSize = CGSizeMake(_scrollView.frame.size.width * _cellCount+2, _scrollView.frame.size.height);if (!CGSizeEqualToSize(_scrollView.contentSize, contentSize)) {_scrollView.contentSize = contentSize;_scrollView.contentOffset = CGPointMake(_scrollView.frame.size.width * _currentCellIndex, 0);}CGRect visibleBounds = _scrollView.bounds;NSInteger newCellIndex = MIN(MAX(floorf(CGRectGetMidX(visibleBounds) / CGRectGetWidth(visibleBounds)), 0), _cellCount - 1);newCellIndex = MAX(0, MIN(_cellCount, newCellIndex));// calculate which pages are visibleNSInteger firstVisibleCell = self.firstVisibleCellIndex;NSInteger lastVisibleCell  = self.lastVisibleCellIndex;NSInteger firstCell = MAX(0,            MIN(firstVisibleCell, newCellIndex - _cellsToPreload));NSInteger lastCell  = MIN(_cellCount-1, MAX(lastVisibleCell,  newCellIndex + _cellsToPreload));// recycle no longer visible cellsNSMutableSet *cellsToRemove = [NSMutableSet set];for (LandscapeCell *cell in _visibleCells) {if (cell.tag < firstCell || cell.tag > lastCell) {[self recycleCell:cell];[cellsToRemove addObject:cell];}}[_visibleCells minusSet:cellsToRemove];// add missing cellsfor (NSInteger index = firstCell; index <= lastCell; index++) {if ([self cellForIndex:index] == nil) {// only preload visible pages in quick modeif (quickMode && (index < firstVisibleCell || index > lastVisibleCell))continue;LandscapeCell *cell = [_dataSource cellInTableView:self atIndex:index];[self configureCell:cell forIndex:index];[_scrollView addSubview:cell];[_visibleCells addObject:cell];}}// update loaded cells infoBOOL loadedCellsChanged = NO;if (quickMode) {// Delay the notification until we actually load all the promised pages.// Also don't update _firstLoadedPageIndex and _lastLoadedPageIndex, so// that the next time we are called with quickMode==NO, we know that a// notification is still needed.//loadedCellsChanged = NO;} else {loadedCellsChanged = (_firstLoadedCellIndex != firstCell || _lastLoadedCellIndex != lastCell);if (loadedCellsChanged) {_firstLoadedCellIndex = firstCell;_lastLoadedCellIndex  = lastCell;}}// update current cell indexBOOL cellIndexChanged = (newCellIndex != _currentCellIndex);if (cellIndexChanged) {_lastCellIndex = _currentCellIndex;_currentCellIndex = newCellIndex;if ([(NSObject *)_delegate respondsToSelector:@selector(tableView:didChangeAtIndex:)])[_delegate tableView:self didChangeAtIndex:_currentCellIndex];}
}- (void)configureCell:(LandscapeCell *)cell forIndex:(NSInteger)index
{cell.tag = index;cell.frame = [self frameForCellAtIndex:index];[cell setNeedsDisplay];
}// It's the caller's responsibility to remove this cell from _visiblePages,
// since this method is often called while traversing _visibleCells array.
- (void)recycleCell:(LandscapeCell *)cell
{if ([cell respondsToSelector:@selector(prepareForReuse)]) {[cell performSelector:@selector(prepareForReuse)];}if (_recyclingEnabled) {[_recycledCells addObject:cell];}[cell removeFromSuperview];
}- (CGRect)frameForScrollView
{CGSize size = self.bounds.size;return CGRectMake(-_gapBetweenCells/2, 0, size.width + _gapBetweenCells, size.height);
}- (CGRect)frameForCellAtIndex:(NSUInteger)index
{CGFloat cellWidthWithGap = _scrollView.frame.size.width;CGSize cellSize = self.bounds.size;return CGRectMake(cellWidthWithGap * index + _gapBetweenCells/2,0, cellSize.width, cellSize.height);
}- (void)willBeginMoving
{if (!_scrollViewIsMoving) {_scrollViewIsMoving = YES;if ([(NSObject *)_delegate respondsToSelector:@selector(tableViewWillBeginMoving:)]) {[_delegate tableViewWillBeginMoving:self];}}
}- (void)didEndMoving
{if (_scrollViewIsMoving) {_scrollViewIsMoving = NO;if (_cellsToPreload > 0) {// we didn't preload invisible cells during scrolling, so now is the time[self configureCells];}if ([(NSObject *)_delegate respondsToSelector:@selector(tableViewDidEndMoving:)]) {[_delegate tableViewDidEndMoving:self];}if (_lastCellIndex != _currentCellIndex) {LandscapeCell *cell = [self cellForIndex:_lastCellIndex];cell.frame = cell.frame;}}
}#pragma mark -
#pragma mark UIScrollViewDelegate methods- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{if (_scrollView == scrollView) {if (_isRotationing)return;[self configureCells];}
}- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{if (_scrollView == scrollView) {[self willBeginMoving];}
}- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{if (!decelerate && _scrollView == scrollView) {[self didEndMoving];}
}- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{if (_scrollView == scrollView) {[self didEndMoving];}
}@end

2.横向滚动单元格TableCell
新建NewsLandscapeCell

//NewsLandscapeCell.h
#import "LandscapeCell.h"
#import "NewsWidget.h"@interface NewsLandscapeCell : LandscapeCell {NewsWidget  *_widget;
}@end
//NewsLandscapeCell.m
#import "NewsLandscapeCell.h"
#import "ColumnInfo.h"
@implementation NewsLandscapeCell- (void)setCellData:(ColumnInfo *)info
{[super setCellData:info];if (_widget == nil) {_widget = [[NewsWidget alloc] init];_widget.columnInfo = info;_widget.owner = self.owner;_widget.view.frame = self.bounds;[self addSubview:_widget.view];}else {_widget.columnInfo = info;[_widget reloadData];}
}@end

3.实现二级栏目导航横向滚动切换

//NewsController.h
IBOutlet LandscapeTableView   *_tableView;
//NewsController.m
#pragma mark - LandscapeViewDataSource & LandscapeViewDelegate methods- (NSInteger)numberOfCellsInTableView:(LandscapeTableView *)tableView
{return _barWidget.listData.count;
}- (LandscapeCell *)cellInTableView:(LandscapeTableView *)tableView atIndex:(NSInteger)index
{NewsLandscapeCell *cell = (NewsLandscapeCell *)[tableView dequeueReusableCell];if (cell == nil) {cell = [[NewsLandscapeCell alloc] initWithFrame:_tableView.bounds];cell.owner = self;}ColumnInfo *info = [_barWidget.listData objectAtIndex:index];[cell setCellData:info];return cell;
}- (void)tableView:(LandscapeTableView *)tableView didChangeAtIndex:(NSInteger)index
{_barWidget.pageIndex = index;
}

新闻内容列表

1.新建新闻列表视图xib,NewsWidget

2.拖拽UITableView控件

3.设置约束,自适应父视图

4.新建xib类,NewsWidget

//NewsWidget.h
#import "TableWidget.h"
#import "ColumnInfo.h"
@interface NewsWidget : TableWidget{BOOL        _hasNextPage;NSInteger   _pageIndex;
}@property(nonatomic, strong) ColumnInfo   *columnInfo;@end
//NewsWidget.m
#import "NewsWidget.h"
#import "GetNews.h"
#import "BaseCell.h"@implementation NewsWidget- (void)viewDidLoad
{self.cellIdentifier = @"NewsCell";_cellHeight = 80;_pageIndex = 0;_hasNextPage = NO;self.listData = [[NSMutableArray alloc] init];[super viewDidLoad];
}- (void)reloadData
{// 停止网络请求[_operation cancelOp];_operation = nil;_pageIndex = 0;// 先清除上次内容[self.listData removeAllObjects];[super reloadData];
}- (BOOL)isReloadLocalData
{//NSArray *datas = [FxDBManager fetchNews:self.columnInfo.ID];//[self.listData addObjectsFromArray:datas];return [super isReloadLocalData];
}- (void)requestServerOp
{NSString *url = [NSString stringWithFormat:NewsURLFmt,self.columnInfo.ID];NSDictionary *dictInfo = @{@"url":url,@"body":self.columnInfo.ID,};_operation = [[GetNews alloc] initWithDelegate:self opInfo:dictInfo];[_operation executeOp];
}- (void)requestNextPageServerOp
{NSString *url = [NSString stringWithFormat:NewsURLFmt,self.columnInfo.ID];NSString *body = [NSString stringWithFormat:@"pageindex=%@",@(_pageIndex)];NSDictionary *dictInfo = @{@"url":url,@"body":body};_operation = [[GetNews alloc] initWithDelegate:self opInfo:dictInfo];[_operation executeOp];
}- (void)opSuccess:(NSArray *)data
{_hasNextPage = YES;_operation = nil;if (_pageIndex == 0) {[self.listData removeAllObjects];}_pageIndex++;[self.listData addObjectsFromArray:data];[self updateUI];[self hideIndicator];
}- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{return indexPath.row < self.listData.count ? _cellHeight:44;
}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{return _hasNextPage?self.listData.count+1:self.listData.count;
}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{NSString *cellIdentifier = nil;BaseInfo *info = nil;if (indexPath.row < self.listData.count) {cellIdentifier = self.cellIdentifier;info = [self.listData objectAtIndex:indexPath.row];}else {cellIdentifier = @"NewsMoreCell";[self requestNextPageServerOp];}BaseCell *cell = (BaseCell*)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];if (cell == nil) {NSArray* Objects = [[NSBundle mainBundle] loadNibNamed:cellIdentifier owner:tableView options:nil];cell = [Objects objectAtIndex:0];[cell initCell];}[cell setCellData:info];return cell;
}
@end

5.设置NewsWidget.xib的File’s owner为NewsWidget
6.新建列表item的TableCell,NewsCell.xib
7.拖拽UIImageView和2个UILabel,分别用来显示缩略图,标题和新闻摘要

8.设置服务器新闻数据,为了方便,我们分别用news_序号来代表每个栏目返回的数据,例如,news_1.json代表第一个栏目数据,news_2.json为第二个栏目,以此类推。

//news_1.json
{"result":"ok","data":[{"id":"AUL8RO0H00014JB6","name":"日众议院表决通过新安保法案","desc":"在反对声中通过新安保法案,将提交参议院审议。","iconurl":"http://img5.cache.netease.com/3g/2015/7/16/2015071609154377b2d.jpg","contenturl":"http://3g.163.com/news/15/0716/13/AUL8RO0H00014JB6.html"},{"id":"AUKG45I500014AED","name":"深圳企业水源保护区建练车场","desc":"事发地毗邻深圳水库,工程未经批复公司入场抢建。","iconurl":"http://img4.cache.netease.com/3g/2015/7/16/201507160855254aa19.jpg","contenturl":"http://3g.163.com/news/15/0716/06/AUKG45I500014AED.html"},{"id":"AUKRS19T0001124J","name":"曝公安部已确定恶意做空对象","desc":"上海个别贸易公司成调查的对象,数千家公司惶恐。","iconurl":"http://img6.cache.netease.com/3g/2015/7/16/201507160943494a1da.jpg","contenturl":"http://3g.163.com/news/15/0716/09/AUKRS19T0001124J.html"},{"id":"3","name":"唐七《三生三世》涉嫌抄袭","desc":"唐七直言被黑,大风则感慨:有人叫抄袭,有人叫模仿","iconurl":"http://img5.cache.netease.com/3g/2015/7/7/20150707155751b64ea.jpg","contenturl":"http://3g.163.com/ent/15/0707/15/ATUBLOMC00031GVS.html"},{"id":"4","name":"张晋带女儿上街 蔡少芬\"吃醋\"","desc":"张晋一手牵大女儿一手拖小女儿,蔡少芬吐槽:那我呢?","iconurl":"http://img5.cache.netease.com/3g/2015/7/7/20150707153619a6fc6.jpg","contenturl":"http://3g.163.com/ntes/15/0707/15/ATUBEV3400963VRR.html"},{"id":"5","name":"唐七《三生三世》涉嫌抄袭","desc":"唐七直言被黑,大风则感慨:有人叫抄袭,有人叫模仿","iconurl":"http://img5.cache.netease.com/3g/2015/7/7/20150707155751b64ea.jpg","contenturl":"http://3g.163.com/ent/15/0707/15/ATUBLOMC00031GVS.html"},{"id":"6","name":"张晋带女儿上街 蔡少芬\"吃醋\"","desc":"张晋一手牵大女儿一手拖小女儿,蔡少芬吐槽:那我呢?","iconurl":"http://img5.cache.netease.com/3g/2015/7/7/20150707153619a6fc6.jpg","contenturl":"http://3g.163.com/ntes/15/0707/15/ATUBEV3400963VRR.html"},{"id":"7","name":"唐七《三生三世》涉嫌抄袭","desc":"唐七直言被黑,大风则感慨:有人叫抄袭,有人叫模仿","iconurl":"http://img5.cache.netease.com/3g/2015/7/7/20150707155751b64ea.jpg","contenturl":"http://3g.163.com/ent/15/0707/15/ATUBLOMC00031GVS.html"}]
}

9.运行程序,cmd+R,如下图,即表示我们新闻列表页开发好了。

github源码:https://github.com/tangthis/NewsReader
个人技术分享微信公众号,欢迎关注一起交流

iOS新闻客户端开发教程7-新闻列表相关推荐

  1. 使用FTP(IOS FTP客户端开发教程)

    本文翻译自新近Wrox出版社出版的,由Peter van de Put所著的<Professional.iOS.Programming>.该书题材比较新颖,结构合理,是一本不错的IOS开发 ...

  2. 《『若水新闻』客户端开发教程》——01.课程介绍

    内容介绍 2011年,若水工作室制作了<Android开发从零开始>系列课程,感谢大家的鼓励和支持.为了进一步提高Android开发培训水平,2012年若水工作室又倾心制作的项目实战视频『 ...

  3. 开篇--基于Android的小巫新闻客户端开发

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 开篇-- ...

  4. 基于安卓的新闻客户端开发

     研究背景 当前市面上移动新闻客户端,包括网易移动新闻客户端,搜狐移动新闻客户端,凤凰移动新闻客户端等.这些客户端界面绚丽,版面较多,操作过程较为复杂.为简化流程,操作简单,方便用户使用和下载.所以, ...

  5. 基于Android的小巫新闻客户端开发--UI设计(主界面)

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 基于An ...

  6. 基于Android小巫新闻客户端开发---显示新闻详细内容UI设计

    基于Android小巫新闻客户端开发---显示新闻详细内容UI设计 2013年2月27日,天气潮湿!!! 距上一次写的主界面业务逻辑实现,已经过来11天,小巫觉得拖得太久了,所以决定尽量把所有的内容介 ...

  7. Android新闻客户端开发3--显示新闻详细内容UI设计

    基于Android小巫新闻客户端开发---显示新闻详细内容UI设计 2013年2月27日,天气潮湿!!! 距上一次写的主界面业务逻辑实现,已经过来11天,小巫觉得拖得太久了,所以决定尽量把所有的内容介 ...

  8. android新闻客户端实验报告,Android 新闻客户端学习笔记

    学习了新闻客户端开发后,有很多是通用的,就把客户端用到的一些做个笔记,已备以后使用,主要用到的知识点有: 1.  Android网络编程 2.  Android中BaseAdapter的使用 3.   ...

  9. iOS 9应用开发教程之使用开关滑块控件以及滚动部署视图

    iOS 9应用开发教程之使用开关滑块控件以及滚动部署视图 使用ios9中的开关.滑块控件 开关和滑块也是用于和用户进行交互的控件.本节将主要讲解这两种控件. ios9开关 开关控件常用来控制某个功能的 ...

最新文章

  1. java 老年代回收_Java垃圾回收之老年代垃圾收集器
  2. ROW_NUMBER() OVER (PARTITION BY 字段1 ORDER BY 字段2 DESC)
  3. IDEA的UML图详细介绍(二)
  4. 【转】MATLAB的polar函数 极坐标绘制最大半径怎样设置
  5. 《SAP 传奇人物》系列人物故事:看透生死远没有操作0和1那么简单
  6. echarts 柱状图 ,颜色和显示设置
  7. IOS开发基础知识--碎片23
  8. 国庆节前梳理一下需要自己干的工作
  9. python如何升级_python pip如何升级
  10. 在vue项目中导入element-ui
  11. 波形发生器设计c语言文件,超低频波形发生器的设计论文(C语言编程) .doc
  12. JEE5标准与Struts/Spring/Hibernate等诸多开源框架的比较分析
  13. python中if语句的实例_如何在Python中的if语句中调用某个函数?
  14. 华为ensp基础指令
  15. dell 恢复介质_Dell Backup and Recovery 1.8:出厂恢复介质
  16. win7安装AHCI驱动
  17. wint_t和wchar_t区别putwchar()iswalpha()iswcntrl()iswdigit()iswpunct()
  18. Python写入word文档
  19. 输入某年某月某日,计算并输出它是这一年的第几天。
  20. [转][酷酷的滕]我爱你语录

热门文章

  1. python运用在大数据中精准生活_在大数据中精准生活阅读理解答案
  2. 计算机专业学校排名北京,计算机专业全国高校排名,你的学校上榜了吗
  3. php 中文文件名
  4. jquery移除元素同时销毁事件
  5. Vue对接支付宝沙箱环境
  6. 我的硬盘居然被win10安装工具_Win10系统安装教程(官方工具)
  7. 如何使用微信签到,实现会议签到功能?实现年会签到功能?
  8. 成年人的奔溃,是从离职不自由开始的
  9. MySQL8.0与MySQL5.7区别
  10. python一般要学几年_怎么自学python,大概要多久?