iOS UITableView 与 UITableViewController实例详解

很多应用都会在界面中使用某种列表控件:用户可以选中、删除或重新排列列表中的项目。这些控件其实都是UITableView 对象,可以用来显示一组对象,例如,用户地址薄中的一组人名。

  UITableView 对象虽然只能显示一行数据,但是没有行数限制。

•编写新的应用程序 JXHomepwner 应用

  创建应用,填写基本信息

•UITableViewController

  UITableView 是视图。我们知道 模型-视图-控制器(Model-View-Controller),他是我们必须遵守的一种设计模式。其含义是,应用创建的任何一个对象,其类型必定是以下三种类型中的一种。

  1. 模型:负责存储数据,与用户界面无关。

  2. 视图:负责显示界面,与模型对象无关。

  3. 控制器:负责确保视图对象和模型对象的数据保持一致。

  一般来说,作为视图对象的 UITableView 不应该负责处理应用的逻辑或数据。当在应用中使用 UITableView 对象的时候,必须考虑如何大啊呸其他的对象,与 UITableView 对象一起工作:

  通常情况下,要通过某个视图控制器对象来创建和释放 UITableView 对象,并负责显示或者隐藏视图。

  UITableView 对象要有数据源才能正常工作。UITableView 对象会向数据源查询要显示的行数,显示表格行所需要的数据和其他所需要的数据。没有数据源的 UITableView 对象只是空壳。凡是遵守 UITableViewDataSource 协议的对象,都可以成为 UITableView 对象的数据源(即dataSource属性所指向的对象)。

  通常情况下,要为 UITableView 对象设置委托对象,以便能在该对象发生特定事件的时候做出相应的处理。凡是遵守 UITableViewDelegate 协议的对象,都可以成为 UITableView 对象的委托对象。

  UITableViewController 对象可以扮演以上全部角色,包括视图控制器对象、数据源和委托对象。

  UITableViewController 是 UIViewController 的子类,所以也有 view 属性。UITableViewController 对象的 view 属性指向一个 UITableView 对象,并且这个对象由 UITableViewController 对象负责设置和显示。UITableViewController 对象会在创建 UITableView 对象后,为这个 UITableView 对象的 dataSource 和 delegate 赋值,并指向自己。

• 创建 UITableViewController 子类

  下面要为我们创建的程序编写一个 UITableViewController 子类。

  UITableViewController 的指定初始化方法是 initWithStyle: 调用 initWithStyle: 时要传入一个类型作为 UITableViewStyle 的常熟,该常熟决定了 UITableView 对象的风格。目前可以使用的 UITableViewStyle 常量有两个,即 UITableViewStylePlain 和 UITableViewStyleGrouped 。

  现在将 UITableViewController 的指定初始化方法改为 init: ,为此时需要遵守两条规则:

  1. 在新的指定初始化方法中调用父类的指定初始化方法。

  2. 覆盖父类的初始化方法,调用新的指定初始化方法。

#import "JXItemsViewController.h"
@interface JXItemsViewController ()
@end
@implementation JXItemsViewController
- (instancetype)init {
// 调用父类的指定初始化方法
self = [super initWithStyle:UITableViewStylePlain];
return self;
}
- (instancetype)initWithStyle:(UITableViewStyle)style {
return [self init];
}
@end

  实现以上两个初始化方法之后,可以确保无论向新创建的 JXItemsViewController 对象发送哪一个初始化方法,初始化后的对象都会使用我们指定的风格。

  接下来代码如下:

#import "AppDelegate.h"
#import "JXItemsViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
// 添加初始化代码
// 创建 JXItemsViewController 对象
JXItemsViewController * itemsViewController = [[JXItemsViewController alloc] init];
// 将 JXItemsViewController 的标示图加入窗口
self.window.rootViewController = itemsViewController;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}

  构建并运行应用我们确实能在屏幕上看到 UITableView 对象。JXItemsViewController 作为 UITableViewController 的子类,集成了 view 方法。 view 方法会调用 loadView 方法,如果视图不存在,则 loadView 方法会创建并载入一个空的视图。

  下面我们要为 UITableView 设置内容。

  新建 JXItem 类

#import <Foundation/Foundation.h>
@interface JXItem : NSObject
/** 创建日期 */
@property (nonatomic,strong,readonly) NSDate * createDate;
/** 名称 */
@property (nonatomic,strong) NSString * itemName;
/** 编号 */
@property (nonatomic,strong) NSString * serialnumber;
/** 价值 */
@property (nonatomic,assign) NSInteger valueInDollars;
/** JXImageStore中的键 */
@property (nonatomic,strong) NSString * itemKey;
+ (instancetype)randomItem;
/**
* JXItem类指定的初始化方法
* @return 类对象
*/
- (instancetype)initWithItemName:(NSString *)name
valueInDollars:(NSInteger)value
serialNumber:(NSString *)sNumber;
- (instancetype)initWithItemName:(NSString *)name;
@end
#import "JXItem.h"
@implementation JXItem
+ (instancetype)randomItem {
// 创建不可变数组对象,包含三个形容词
NSArray * randomAdjectiveList = @[
@"Fluffy",
@"Rusty",
@"Shiny"
];
// 创建不可变数组对象,包含三个名词
NSArray * randomNounList = @[
@"Bear",
@"Spork",
@"Mac"
];
// 根据数组对象所含的对象的个数,得到随机索引
// 注意:运算符%是模运算符,运算后得到的是余数
NSInteger adjectiveIndex = arc4random() % randomAdjectiveList.count;
NSInteger nounIndex = arc4random() % randomNounList.count;
// 注意,类型为NSInteger 的变量不是对象
NSString * randomName = [NSString stringWithFormat:@"%@ %@",randomAdjectiveList[adjectiveIndex],randomNounList[nounIndex]];
NSInteger randomValue = arc4random_uniform(100);
NSString * randomSerialNumber = [NSString stringWithFormat:@"%c%c%c%c",
'0' + arc4random_uniform(10),
'A' + arc4random_uniform(26),
'0' + arc4random_uniform(10),
'A' + arc4random_uniform(26)];
JXItem * newItem = [[self alloc] initWithItemName:randomName
valueInDollars:randomValue
serialNumber:randomSerialNumber];
return newItem;
}
- (NSString *)description {
NSString * descriptionString = [NSString stringWithFormat:@"%@ (%@):Worth $%zd, recorded on %@",self.itemName,self.serialnumber,self.valueInDollars,self.createDate];
return descriptionString;
}
- (instancetype)initWithItemName:(NSString *)name
valueInDollars:(NSInteger)value
serialNumber:(NSString *)sNumber {
// 调用父类的指定初始化方法
self = [super init];
// 父类的指定初始化方法是否成功创建了对象
if (self) {
// 为实例变量设置初始值
_itemName = name;
_valueInDollars = value;
_serialnumber = sNumber;
// 设置_createDate为当前时间
_createDate = [NSDate date];
// 创建一个 NSUUID 对象
NSUUID * uuid = [[NSUUID alloc] init];
NSString * key = [uuid UUIDString];
_itemKey = key;
}
// 返回初始化后的对象的新地址
return self;
}
- (instancetype)initWithItemName:(NSString *)name {
return [self initWithItemName:name valueInDollars:0 serialNumber:@""];
}
- (instancetype)init {
return [self initWithItemName:@"Item"];
}
- (void)dealloc {
NSLog(@"Destoryed:%@",self);
}
@end

•UITableView 数据源

  创建JXItemStore

  JXItemStore 对象是一个单例,也就是说,每个应用只会有一个这种类型的对象。如果应用尝试创建另一个对象,JXItemStore类就会返回已经存在的那个对象。当某个程序要在很多不同的代码段中使用同一个对象时,将这个对象设置为单例是一种很好的设计模式,只需要向该对象的类发送特定的方法,就可以得到相同的对象。

#import <Foundation/Foundation.h>
@interface JXItemStore : NSObject
// 注意,这是一个类方法,前缀是+
+ (instancetype)sharedStore;
@end
  在 JXItemStore 类收到 sharedStore 消息后,会检查自己是否已经创建 JXItemStore 的单例对象。如果已经创建,就返回自己已经创建的对象,否则就需要先创建,然后再返回。
#import "JXItemStore.h"
@implementation JXItemStore
// 单粒对象
+ (instancetype)sharedStore {
static JXItemStore * sharedStore = nil;
// 判断是否需要创建一个 sharedStore 对象
if (!sharedStore) {
sharedStore = [[self alloc] init];
}
return sharedStore;
}
@end

  这段代码将 sharedStore 指针声明了 静态变量。当某个定义了静态变量的方法返回时,程序不会释放相应的变量。静态变量和全局变量一样,并不是保存在栈中的。

  sharedStore 变量的初始值为 nil。当程序第一次执行 sharedStore 方法时,会创建一个 JXItemStore 对象,并将新创建的对象的地址赋值给 sharedStore 变量。当程序再次执行 sharedStore 方法时,不管是第几次,其指针总是指向最初创建的那个对象。因为指向 JXItemStore 对象的 sharedStore 变量是强引用,且程序永远不会释放该变量,所以 sharedStore 变量所指向的 JXItemStore 对象永远也不会被释放。

  JXItemsViewController 需要创建一个新的 JXItem 对象时会向 JXItemStore 对象发送消息,收到消息的 JXItemStore 对象会创建一个 JXItem 对象并将其保存到一个 JXItem 数组中,之后 JXItemsViewController 可以通过该数组获取所有 JXItem 对象,并使用这些对象填充自己的表视图。

#import <Foundation/Foundation.h>
@class JXItem;
@interface JXItemStore : NSObject
/** 存放 JXItem 对象数组 */
@property (nonatomic,readonly) NSArray * allItem;
// 注意,这是一个类方法,前缀是+
+ (instancetype)sharedStore;
- (JXItem *)createItem;
@end 

  在实现文件中编辑。但是我们需要注意,在我们的应用中将使用 JXItemStore 管理 JXItem 数组-包括添加、删除和排序。因此,除 JXItemStore 之外的类不应该对 JXItem 数组做这些操作。在 JXItemStore 内部,需要将 JXItem 数组定义为可变数组。而对其他类来说,JXItem 数组则是不可变的数组。这是一种常见的设计模式,用于设置内部数据的访问权限:某个对象中有一种可修改的数据,但是除该对象本身之外,其他对象只能访问该数据而不能修改它。

#import "JXItemStore.h"
#import "JXItem.h"
@interface JXItemStore ()
/** 可变数组,用来操作 JXItem 对象 */
@property (nonatomic,strong) NSMutableArray * privateItems;
@end
@implementation JXItemStore
// 单粒对象
+ (instancetype)sharedStore {
static JXItemStore * sharedStore = nil;
// 判断是否需要创建一个 sharedStore 对象
if (!sharedStore) {
sharedStore = [[self alloc] init];
}
return sharedStore;
}
- (NSArray *)allItem {
return self.privateItems;
}
#pragma mark - 懒加载
- (NSMutableArray *)privateItems{
if (_privateItems == nil) {
_privateItems = [[NSMutableArray alloc] init];
}
return _privateItems;
}
@end

  allItem 方法的返回值是 NSArray 类型,但是方法体中返回的是 NSMutableArray 类型的对象,这种写法是正确的,因为NSMutableArray 是 NSArray 子类。

  这种写法可能会引起一个问题:虽然头文件中将 allItem 的类型声明为 NSArray ,但是其他对象调用 JXItemStore 的 allItem 方法时,得到的一定是一个 NSMutableArray 对象。

  使用像 JXItemStore 这样的类时,应该遵守其头文件中的声明使用类的属性和方法。 例如,在 JXItemStore 头文件中,因为 allItem 属性的类型是 NSArray ,所以应该将其作为 NASrray 类型的对象使用。如果将 allItem 转换为 NSMutableArray 类型并修改其内容,就违反了 JXItemStore 头文件中的声明。可以通过覆盖 allItem 方法避免其他类修改 allItem 。

#import "JXItemStore.h"
#import "JXItem.h"
@interface JXItemStore ()
/** 可变数组,用来操作 JXItem 对象 */
@property (nonatomic,strong) NSMutableArray * privateItems;
@end
@implementation JXItemStore
// 单粒对象
+ (instancetype)sharedStore {
static JXItemStore * sharedStore = nil;
// 判断是否需要创建一个 sharedStore 对象
if (!sharedStore) {
sharedStore = [[self alloc] init];
}
return sharedStore;
}
- (NSArray *)allItem {
return [self.privateItems copy];
}
- (JXItem *)createItem {
JXItem * item = [JXItem randomItem];
[self.privateItems addObject:item];
return item;
}
#pragma mark - 懒加载
- (NSMutableArray *)privateItems{
if (_privateItems == nil) {
_privateItems = [[NSMutableArray alloc] init];
}
return _privateItems;
}
@end

  实现数据源方法  

#import "JXItemsViewController.h"
#import "JXItem.h"
#import "JXItemStore.h"
@interface JXItemsViewController ()
@end
@implementation JXItemsViewController
- (instancetype)init {
// 调用父类的指定初始化方法
self = [super initWithStyle:UITableViewStylePlain];
if (self) {
for (NSInteger i=0; i<5; i++) {
[[JXItemStore sharedStore] createItem];
}
}
return self;
}
- (instancetype)initWithStyle:(UITableViewStyle)style {
return [self init];
}
@end

  当某个 UITableView 对象要显示表格内容时,会向自己的数据源(dataSource 属性所指向的对象)发送一系列消息,其中包括必须方法和可选方法。

@required
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
@optional
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; // Default is 1 if not implemented
- (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section; // fixed font style. use custom view (UILabel) if you want something different
- (nullable NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;
// Editing
// Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;
// Moving/reordering
// Allows the reorder accessory view to optionally be shown for a particular row. By default, the reorder control will be shown only if the datasource implements -tableView:moveRowAtIndexPath:toIndexPath:
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;
// Index
- (nullable NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView __TVOS_PROHIBITED; // return list of section titles to display in section index view (e.g. "ABCD...Z#")
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index __TVOS_PROHIBITED; // tell table which section corresponds to section title/index (e.g. "B",1))
// Data manipulation - insert and delete support
// After a row has the minus or plus button invoked (based on the UITableViewCellEditingStyle for the cell), the dataSource must commit the change
// Not called for edit actions using UITableViewRowAction - the action's handler will be invoked instead
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;
// Data manipulation - reorder / moving support
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;
@end

  实现行数代码

#import "JXItemsViewController.h"
#import "JXItem.h"
#import "JXItemStore.h"
@interface JXItemsViewController ()
@end
@implementation JXItemsViewController
- (instancetype)init {
// 调用父类的指定初始化方法
self = [super initWithStyle:UITableViewStylePlain];
if (self) {
for (NSInteger i=0; i<5; i++) {
[[JXItemStore sharedStore] createItem];
}
}
return self;
}
- (instancetype)initWithStyle:(UITableViewStyle)style {
return [self init];
}
- (void)viewDidLoad {
[super viewDidLoad];
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[[JXItemStore sharedStore] allItem] count];
}
@end

  UITableViewDataSource 协议中的另外一个必须实现的方法

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  在此之前,我们需要先了解另一个类:UITableViewCell

•UITableViewCell 对象

  表视图所显示的每一行都是一个独立的视图,这些视图是 UITableViewCell 对象。其对象还有一个子视图:contentView 。contentView 也包含了很多子视图,他的子视图构成 UITableViewCell 对象的主要外观。此外, UITableViewCell 对象还可以显示一个辅助指示图。辅助指示视图的作用是显示一个指定的图标,用于向用户提示 UITableViewCell 对象可以执行的动作。这些图标包括勾起标记、展开图标或中间有v形团的蓝色圆点。其默认是 UITableViewCellAccessoryNone 。

  在创建 UITableViewCell 对象时,可以选择不同的风格来决定 UITableViewCell 对象显示。

typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
UITableViewCellStyleDefault, // Simple cell with text label and optional image view (behavior of UITableViewCell in iPhoneOS 2.x)
UITableViewCellStyleValue1, // Left aligned label on left and right aligned label on right with blue text (Used in Settings)
UITableViewCellStyleValue2, // Right aligned label on left with blue text and left aligned label on right (Used in Phone/Contacts)
UITableViewCellStyleSubtitle // Left aligned label on top and left aligned label on bottom with gray text (Used in iPod).
}; // available in iPhone OS 3.0

  创建并获取 UITableViewCell 对象

  下面我们主要对 tableView: cellForRowAtIndexPath: 方法进行改写。首先我们需要将 JXItem 数据跟 UITableViewCell 对象对应起来。在方法中有一个实参是 NSIndexPath 对象,该对象包含两个属性 section(段) 和 row(行) 。当 UITableView 对象向其数据源发送 tableView: cellForRowAtIndexPath: 消息时,其目的是获取显示第 section 个表格段、第 row 行数据的 UITableViewCell 对象。

#import "JXItemsViewController.h"
#import "JXItem.h"
#import "JXItemStore.h"
@interface JXItemsViewController ()
@end
@implementation JXItemsViewController
- (instancetype)init {
// 调用父类的指定初始化方法
self = [super initWithStyle:UITableViewStylePlain];
if (self) {
for (NSInteger i=0; i<15; i++) {
[[JXItemStore sharedStore] createItem];
}
}
return self;
}
- (instancetype)initWithStyle:(UITableViewStyle)style {
return [self init];
}
- (void)viewDidLoad {
[super viewDidLoad];
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[[JXItemStore sharedStore] allItem] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 创建 UITableViewCell 对象,风格使用默认风格
UITableViewCell * cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@"UITableViewCell"];
// 获取 allItem 的第 n 个 JXItem 对象
// 然后将该 JXItem 对象的描述信息赋值给 UITableViewCell 对象的 textLabel
// 这里的 n 是该 UITableViewCell 对象所对应的表格索引
NSArray * items = [[JXItemStore sharedStore] allItem];
JXItem * item = items[indexPath.row];
cell.textLabel.text = [item description];
return cell;
}
@end

  构建并运行

  重用UITableViewCell对象

  iOS设备内存是有限的,如果某个 UITableView 对象要显示大量的记录,并且要针对每条记录创建相应的 UITableViewCell 对象,就会很快耗尽iOS设备内存。

  在 UITableView 上存在大量可优化的地方,其中最重要的就是关于 UITableViewCell 复用问题。因为当我们滑动界面是,大多数的 cell表格都会移出窗口,移出窗口的 UITableViewCell 对象放入 UITableViewCell 对象池,等待重用。当 UITableView 对象要求数据源返回某个 UITableViewCell 对象时,就可以先查看对象池。如果有未使用的 UITableViewCell 对象,就可以用新的数据配置这个 UITableViewCell 对象,然后将其返回给 UITableView 对象,从而避免了创建新的对象,可以极大的优化内存。

  但是这里还会有一个问题:如果我们在 UITableView 对象中创建了不同的 UITableViewCell 表格,用来展示不同的信息。那么这时候 UITableViewCell 对象池中的对象就会存在不同的类型,那么 UItableView 就有可能会得到错误的类型的 UITableViewCell 对象。鉴于上述原因,必须保证 UITableView 对象能够得到正确的指定类型的 UITableViewCell 对象,这样才能确定返回的对象会拥有哪些属性和方法。

  从 UITableViewCell 对象池获取对象时,无需关心取回的是否是某个特性的对象,因为无论取回来的是哪个对象,都要重新设置数据。真正要关心的是取回来的对象是否是某个特性的类型。每个 UITableViewCell 对象都有一个类型为 NSString 的 reuseIdentifier 属性。当数据源向 UITableView 对象获取可重用的 UITableViewCell 对象时,可传入一个字符串并要求 UITableView 对象返回相应的 UITableViewCell 对象。

#import "JXItemsViewController.h"
#import "JXItem.h"
#import "JXItemStore.h"
@interface JXItemsViewController ()
@end
@implementation JXItemsViewController
- (instancetype)init {
// 调用父类的指定初始化方法
self = [super initWithStyle:UITableViewStylePlain];
if (self) {
for (NSInteger i=0; i<15; i++) {
[[JXItemStore sharedStore] createItem];
}
}
return self;
}
- (instancetype)initWithStyle:(UITableViewStyle)style {
return [self init];
}
- (void)viewDidLoad {
[super viewDidLoad];
// 向控制器注册
[self.tableView registerClass:[UITableViewCell class]
forCellReuseIdentifier:@"UITableViewCell"];
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[[JXItemStore sharedStore] allItem] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 创建 UITableViewCell 对象,风格使用默认风格
UITableViewCell * cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@"UITableViewCell"];
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"
forIndexPath:indexPath];
// 获取 allItem 的第 n 个 JXItem 对象
// 然后将该 JXItem 对象的描述信息赋值给 UITableViewCell 对象的 textLabel
// 这里的 n 是该 UITableViewCell 对象所对应的表格索引
NSArray * items = [[JXItemStore sharedStore] allItem];
JXItem * item = items[indexPath.row];
cell.textLabel.text = [item description];
return cell;
}
@end

以上所述是小编给大家介绍的iOS UITableView 与 UITableViewController实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • 改变iOS应用中UITableView的背景颜色与背景图片的方法

    改变UITableView的header.footer背景颜色 改变UITableView的header.footer背景颜色,这是个很常见的问题.之前知道的一般做法是,通过实现tableView: viewForHeaderInSection:返回一个自定义的View,里面什么都不填,只设背景颜色.但是今天发现一个更简洁的做法: 对于iOS 6及以后的系统,实现这个新的delegate函数即可: 复制代码 代码如下: - (void)tableView:(UITableView *)table

  • 详解iOS开发中UITableview cell 顶部空白的多种设置方法

    我知道没人会主动设置这个东西,但是大家一定都遇到过这个问题,下面总结下可能是哪些情况: 1, self.automaticallyAdjustsScrollViewInsets = NO; 这个应该是最常见而且不容易被发现的原因,起因是iOS7在Conttoller中新增了automaticallyAdjustsScrollViewInsets这个属性,当设置为YES时(默认YES),如果视图里面存在唯一一个UIScrollView或其子类View,那么它会自动设置相应的内边距,这样可以让scr

  • iOS应用开发中UITableView的分割线的一些设置技巧

    对于ios7,ios8及以上来说,调整UITableView的cell的分割线位置已经是相当不便,因为UITableView内部使用了margin layout. 其实只需要如下这样子就可以实现分割线的控制. 复制代码 代码如下: -(void)tableView:(UITableView )tableView willDisplayCell:(UITableViewCell )cell forRowAtIndexPath:(NSIndexPath *)indexPath {     // 下面

  • iOS App中UITableView左滑出现删除按钮及其cell的重用

    UITableView的编辑模式 实现UITableView简单的删除功能(左滑出现删除按钮) 首先UITableView需要进入编辑模式.实现下面的方法,即使什么代码也不写也会进入编辑模式: 复制代码 代码如下: - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)index

  • 全面解析iOS应用中自定义UITableViewCell的方法

    有时候我们需要自己定义UITableViewCell的风格,其实就是向行中添加子视图.添加子视图的方法主要有两种:使用代码以及从.xib文件加载.当然后一种方法比较直观. 一.基本用法 我们这次要自定义一个Cell,使得它像QQ好友列表的一行一样:左边是一张图片,图片的右边是三行标签: 当然,我们不会搞得这么复杂,只是有点意思就行. 1.运行Xcode 4.2,新建一个Single View Application,名称为Custom Cell: 2.将图片资源导入到工程.为此,我找了14张50

  • 详解iOS开发中UItableview控件的数据刷新功能的实现

    实现UItableview控件数据刷新 一.项目文件结构和plist文件 二.实现效果 1.说明:这是一个英雄展示界面,点击选中行,可以修改改行英雄的名称(完成数据刷新的操作). 运行界面: 点击选中行: 修改数据后自动刷新: 三.代码示例 数据模型部分: YYheros.h文件 复制代码 代码如下: // //  YYheros.h //  10-英雄展示(数据刷新) // //  Created by apple on 14-5-29. //  Copyright (c) 2014年 itc

  • IOS UITableViewCell详解及按钮点击事件处理实例

    IOS UITableViewCell详解及按钮点击事件处理 今天突然做项目的时候,又遇到处理自定义的UITableViewCell上按钮的点击事件问题.我知道有两种方式,可是突然想不起来之前是怎么做的了,好记性不如烂笔头,还是记录一下吧. 1.第一种方式给Button加上tag值 这里分为两种:一种是直接在原生的UITableViewCell上添加UIButton按钮,然后给UIButton设置tag值,然后在控制器里的方法里通过取数据,做界面跳转等.还是举个例子吧,省的回忆半天. - (UI

  • IOS 开发之UITableView 删除表格单元写法

    IOS 开发之UITableView 删除表格单元写法 实现代码: - (void)tableView:(UITableView *)aTableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { NSDiction

  • iOS UITableView 与 UITableViewController实例详解

    很多应用都会在界面中使用某种列表控件:用户可以选中.删除或重新排列列表中的项目.这些控件其实都是UITableView 对象,可以用来显示一组对象,例如,用户地址薄中的一组人名. UITableView 对象虽然只能显示一行数据,但是没有行数限制. •编写新的应用程序 JXHomepwner 应用 创建应用,填写基本信息 •UITableViewController UITableView 是视图.我们知道 模型-视图-控制器(Model-View-Controller),他是我们必须遵守的一种

  • IOS 绘制三角形的实例详解

    IOS 绘制三角形的实例详解 先上效果图 上面三角形的代码 - (void)ljTestView { CGPoint piont1; piont1.x = 170; piont1.y = 100; CGPoint piont2; piont2.x = 50; piont2.y = 200; CGPoint piont3; piont3.x = 220; piont3.y = 200; ljDrawRect *_ljView = [[ljDrawRect alloc]initStartPoint:

  • IOS 获取网络图片大小实例详解

    IOS 获取网络图片大小实例详解 在iOS开发过程中经常需要通过网络请求加载图片,有时,需要在创建UIImageView或UIButton来显示图片之前需要提前知道图片的尺寸,根据图片尺寸创建对应大小的控件.但是对于网络图片来说,要想通过最优的方法获得尺寸就略微有点困难,大体思路就是下面这种: 如果有使用SDWebImage,则首先检查是否缓存过该图片,如果没有,先通过文件头获取图片大小(针对格式为png.gif.jpg文件获取其尺寸大小),如果获取失败,则下载完整的图片data,然后计算大小,

  • IOS 基本文件操作实例详解

    IOS 基本文件操作实例详解 在iOS的App沙盒中,Documents和Library/Preferences都会被备份到iCloud,因此只适合放置一些记录文件,例如plist.数据库文件.缓存一般放置到Library/Caches,tmp文件夹会被系统随机清除,不适宜防止数据. [图片缓存的清除] 在使用SDWebImage时,图片被大量的缓存,有时需要获取缓存的大小以及清除缓存. 要获取缓存大小,使用SDImageCache单例的getSize方法拿到byte为单位的缓存大小,注意计算时

  • IOS代码修改音量实例详解

    IOS代码修改音量实例详解 最近在做一个项目,需要用户在打开APP后,自动将音量调节到某个值,于是研究了一下. 之前做过iOS上声音的研究,苹果对iPhone设备的输入/输出的控制很严格,因为苹果要控制用户体验的一致性.比如:用户将耳机拔下来的时候,苹果认为,用户这时候不希望其他人知道自己在听什么,于是这时候声音会被自动暂停.在音量调整上,苹果也采取了类似的策略.苹果认为,用户不需要APP来为他指定音量,因为这样有时候用户会感到不舒服.苹果的开发文档是这么说的: You cannot chang

  • IOS 粒子系统 (CAEmitterLayer)实例详解

    一.系统剖析 在UIKit中,粒子系统由两部分组成: ·      一个或多个CAEmitterCells:发射器电池可以看作是单个粒子的原型(例如,一个单一的粉扑在一团烟雾).当散发出一个粒子,UIKit根据这个发射粒子和定义的基础上创建一个随机粒子.此原型包括一些属性来控制粒子的图片,颜色,方向,运动,缩放比例和生命周期. ·      一个或多个CAEmitterLayers,但通常只有一个:这个发射的层主要控制粒子的形状(例如,一个点,矩形或圆形)和发射的位置(例如,在矩形内,或边缘).

  • IOS 代理方式实现实例详解

    IOS 代理方式实现 在客户端开发中,经常用到通知.代理.block来实现各个页面之间关联.通知,以一直"盲"的方式实现传递. 代理.block 可以很明确的知道各个界面之间的关联关系.以代理为例,一般的做法如下 : DesViewController *des = [[DesViewController alloc] init];des.delegate = self;[self.navigationController pushViewController:des animated

  • iOS socket网络编程实例详解

    代码下载 服务端代码下载地址 客户端代码下载地址 相关概念 socket是一个针对TCP和UDP编程的接口,你可以借助它建立TCP连接等.socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议.Socket的出现只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,从而形成了我们知道的一些最基本的函数接口. socket连接:socket连接就是所谓的长连接,理论上客户端和服务器端一旦

  • IOS UITableView颜色设置的实例详解

    IOS UITableView颜色设置的实例详解 1.系统默认的颜色设置  //无色 cell.selectionStyle = UITableViewCellSelectionStyleNone; //蓝色 cell.selectionStyle = UITableViewCellSelectionStyleBlue; //灰色 cell.selectionStyle = UITableViewCellSelectionStyleGray; 2.自定义颜色和背景设置 改变UITableView

  • IOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解 在实际的开发需求时,有时候我们需要对某些对象进行打包,最后拼接到参数中 例如,我们把所有的参数字典打包为一个 字符串拼接到参数中 思路:利用系统系统JSON序列化类即可,NSData作为中间桥梁 //1.字典转换为字符串(JSON格式),利用 NSData作为桥梁; NSDictionary *dic = @{@"name":@"Lisi",@"sex":@"m",@"tel&qu

随机推荐