2011年8月26日
UITableView是app開發(fā)中常用到的控件,功能很強大,多用于數(shù)據(jù)的顯示。下面以一個簡單的實例來介紹tableview的基本用法。(適合新手,高手飄過)

- @interface TableViewTestViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>{
-
- UITableView *DataTable;
-
- NSMutableArray *dataArray1; //定義數(shù)據(jù)數(shù)組1
-
- NSMutableArray *dataArray2;//定義數(shù)據(jù)數(shù)組2
-
- NSMutableArray *titleArray;//定義標題數(shù)組
-
- }
-
-
-
- - (void)viewDidLoad
-
- {
-
- [superviewDidLoad];
-
- //初始化tableview
-
- DataTable = [[UITableViewalloc] initWithFrame:CGRectMake(0, 0, 320, 420)];//指定位置大小
-
- [DataTablesetDelegate:self];//指定委托
-
- [DataTablesetDataSource:self];//指定數(shù)據(jù)委托
-
- [self.viewaddSubview:DataTable];//加載tableview
-
-
-
- dataArray1 = [[NSMutableArrayalloc] initWithObjects:@"中國", @"美國", @"英國", nil];//初始化數(shù)據(jù)數(shù)組1
-
- dataArray2 = [[NSMutableArrayalloc] initWithObjects:@"黃種人", @"黑種人", @"白種人", nil];//初始化數(shù)據(jù)數(shù)組2
-
- titleArray = [[NSMutableArrayalloc] initWithObjects:@"國家", @"種族", nil];//初始化標題數(shù)組
-
-
-
- }
-
-
-
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
-
- {
-
- // Return YES for supported orientations
-
- return (interfaceOrientation == UIInterfaceOrientationPortrait);
-
- }
-
-
-
-
-
- //每個section顯示的標題
-
- - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
-
- switch (section) {
-
- case 0:
-
- return [titleArray objectAtIndex:section];//提取標題數(shù)組的元素用來顯示標題
-
- case 1:
-
- return [titleArray objectAtIndex:section];//提取標題數(shù)組的元素用來顯示標題
-
- default:
-
- return @"Unknown";
-
- }
-
-
-
- }
-
-
-
- //指定有多少個分區(qū)(Section),默認為1
-
- - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
-
- return [titleArray count];//返回標題數(shù)組中元素的個數(shù)來確定分區(qū)的個數(shù)
-
- }
-
-
-
- //指定每個分區(qū)中有多少行,默認為1
-
- - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
-
- switch (section) {
-
- case 0:
-
- return [dataArray1 count];//每個分區(qū)通常對應不同的數(shù)組,返回其元素個數(shù)來確定分區(qū)的行數(shù)
-
- break;
-
- case 1:
-
- return [dataArray2 count];
-
- break;
-
- default:
-
- return 0;
-
- break;
-
- }
-
- }
-
-
-
- //繪制Cell
-
- -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
-
-
-
- static NSString *CellIdentifier = @"Cell";
-
- //初始化cell并指定其類型,也可自定義cell
-
- UITableViewCell *cell = (UITableViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
-
- if(cell == nil)
-
- {
-
- cell = [[[UITableViewCellalloc]
-
- initWithFrame:CGRectZero
-
- reuseIdentifier:CellIdentifier] autorelease];
-
- }
-
- switch (indexPath.section) {
-
- case 0://對應各自的分區(qū)
-
- [[cell textLabel] setText:[dataArray1 objectAtIndex:indexPath.row]];//給cell添加數(shù)據(jù)
-
- break;
-
- case 1:
-
- [[cell textLabel] setText:[dataArray2 objectAtIndex:indexPath.row]];
-
- break;
-
- default:
-
- [[cell textLabel] setText:@"Unknown"];
-
- }
-
- return cell;//返回cell
-
- }
上面的例子在功能上介紹了tableview的使用,但其在數(shù)據(jù)處理上具有很大的局限性。當我們要從服務器上請求數(shù)據(jù),面對多種可能的數(shù)據(jù)(主要指數(shù)組的個數(shù)不穩(wěn)定)此時上面的switch將無法滿足我們的需求了。使用switch可是代碼的結(jié)構清晰明了,但其局限性很致命(switch中case的個數(shù)無法動態(tài)指定),下面的另一種方法可解決上述問題。

代碼在原由基礎上進行的修改:
- @interface TableViewTestViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>{
-
- UITableView *DataTable;
-
- NSMutableArray *dataArray1;
-
- NSMutableArray *dataArray2;
-
- NSMutableArray *titleArray;
-
- NSMutableArray *dataArray; //加入了用于保存數(shù)組的數(shù)組 dataArray
-
- }
-
-
-
- - (void)viewDidLoad
-
- {
-
- [superviewDidLoad];
-
- DataTable = [[UITableViewalloc] initWithFrame:CGRectMake(0, 0, 320, 420)];
-
- [DataTablesetDelegate:self];
-
- [DataTablesetDataSource:self];
-
- [self.viewaddSubview:DataTable];
-
-
-
- dataArray1 = [[NSMutableArrayalloc] initWithObjects:@"中國", @"美國", @"英國", nil];
-
- dataArray2 = [[NSMutableArrayalloc] initWithObjects:@"黃種人", @"黑種人", @"白種人", nil];
-
- titleArray = [[NSMutableArrayalloc] initWithObjects:@"國家", @"種族", nil];
-
- dataArray = [[NSMutableArrayalloc] initWithObjects:dataArray1, dataArray2, nil]; //初始化dataArray,元素為數(shù)組
-
-
-
- }
-
-
-
-
-
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
-
- {
-
- // Return YES for supported orientations
-
- return (interfaceOrientation == UIInterfaceOrientationPortrait);
-
- }
-
- //制定個性標題,這里通過UIview來設計標題,功能上豐富,變化多。
-
- - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
-
- UIView *view = [[[UIViewalloc] initWithFrame:CGRectMake(0, 0, 320, 40)] autorelease];
-
- [view setBackgroundColor:[UIColorbrownColor]];//改變標題的顏色,也可用圖片
-
- UILabel *label = [[UILabelalloc] initWithFrame:CGRectMake(5, 5, 100, 30)];
-
- label.textColor = [UIColorredColor];
-
- label.backgroundColor = [UIColorclearColor];
-
- label.text = [titleArrayobjectAtIndex:section];
-
- [view addSubview:label];
-
- return view;
-
- }
-
- //指定標題的高度
-
- - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
-
- return 40;
-
- }
-
-
-
- //每個section顯示的標題,有了上面的這個就不要了
-
- - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
-
- }
-
-
-
- //指定有多少個分區(qū)(Section),默認為1
-
- - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
-
- return [titleArraycount];
-
- }
-
-
-
- //指定每個分區(qū)中有多少行,默認為1
-
- - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
-
- /* switch (section) {
-
- case 0:
-
- return [dataArray1 count];
-
- break;
-
- case 1:
-
- return [dataArray2 count];
-
- break;
-
- default:
-
- return 0;
-
- break;
-
- }*/
-
- /* for(int i = 0; i < [titleArray count]; i++){
-
- if(section == i){
-
- return [[dataArray objectAtIndex:section] count];
-
- }
-
- }*/
-
- //上面的方法也是可行的,大家參考比較下
-
- return [[dataArray objectAtIndex:section] count]; //取dataArray中的元素,并根據(jù)每個元素(數(shù)組)來判斷分區(qū)中的行數(shù)。
-
-
-
-
-
- }
-
-
-
- //繪制Cell
-
- -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
-
-
-
- static NSString *CellIdentifier = @"Cell";
-
-
-
- UITableViewCell *cell = (UITableViewCell*)[tableView
-
- dequeueReusableCellWithIdentifier:CellIdentifier];
-
- if(cell == nil)
-
- {
-
- cell = [[[UITableViewCellalloc]
-
- initWithFrame:CGRectZero
-
- reuseIdentifier:CellIdentifier] autorelease];
-
- }
-
-
-
- /*switch (indexPath.section) {
-
- case 0:
-
- [[cell textLabel]
-
- setText:[dataArray1 objectAtIndex:indexPath.row]];
-
- break;
-
- case 1:
-
- [[cell textLabel]
-
- setText:[dataArray2 objectAtIndex:indexPath.row]];
-
- break;
-
- default:
-
- [[cell textLabel]
-
- setText:@"Unknown"];
-
- }*/
-
- //上面的方法也可行,大家比較下。
-
- [[cell textLabel] setText:[[dataArrayobjectAtIndex:indexPath.section]objectAtIndex:indexPath.row]];
-
- //同上,取出dataArray中每個分區(qū)所對應的元素(數(shù)組),并通過其來取值。 (大家要有想像力, 復制代碼試試就明白了)
-
-
-
- return cell;
-
-
-
- }
-
-
-
- //改變行的高度
-
- - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
-
- return40;
-
- }
轉(zhuǎn)自:http://www.cnblogs.com/top5/archive/2012/05/17/2506604.html
UITableView是app開發(fā)中常用到的控件,功能很強大,多用于數(shù)據(jù)的顯示。下面以一個簡單的實例來介紹tableview的基本用法。(適合新手,高手飄過)

- @interface TableViewTestViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>{
-
- UITableView *DataTable;
-
- NSMutableArray *dataArray1; //定義數(shù)據(jù)數(shù)組1
-
- NSMutableArray *dataArray2;//定義數(shù)據(jù)數(shù)組2
-
- NSMutableArray *titleArray;//定義標題數(shù)組
-
- }
-
-
-
- - (void)viewDidLoad
-
- {
-
- [superviewDidLoad];
-
- //初始化tableview
-
- DataTable = [[UITableViewalloc] initWithFrame:CGRectMake(0, 0, 320, 420)];//指定位置大小
-
- [DataTablesetDelegate:self];//指定委托
-
- [DataTablesetDataSource:self];//指定數(shù)據(jù)委托
-
- [self.viewaddSubview:DataTable];//加載tableview
-
-
-
- dataArray1 = [[NSMutableArrayalloc] initWithObjects:@"中國", @"美國", @"英國", nil];//初始化數(shù)據(jù)數(shù)組1
-
- dataArray2 = [[NSMutableArrayalloc] initWithObjects:@"黃種人", @"黑種人", @"白種人", nil];//初始化數(shù)據(jù)數(shù)組2
-
- titleArray = [[NSMutableArrayalloc] initWithObjects:@"國家", @"種族", nil];//初始化標題數(shù)組
-
-
-
- }
-
-
-
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
-
- {
-
- // Return YES for supported orientations
-
- return (interfaceOrientation == UIInterfaceOrientationPortrait);
-
- }
-
-
-
-
-
- //每個section顯示的標題
-
- - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
-
- switch (section) {
-
- case 0:
-
- return [titleArray objectAtIndex:section];//提取標題數(shù)組的元素用來顯示標題
-
- case 1:
-
- return [titleArray objectAtIndex:section];//提取標題數(shù)組的元素用來顯示標題
-
- default:
-
- return @"Unknown";
-
- }
-
-
-
- }
-
-
-
- //指定有多少個分區(qū)(Section),默認為1
-
- - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
-
- return [titleArray count];//返回標題數(shù)組中元素的個數(shù)來確定分區(qū)的個數(shù)
-
- }
-
-
-
- //指定每個分區(qū)中有多少行,默認為1
-
- - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
-
- switch (section) {
-
- case 0:
-
- return [dataArray1 count];//每個分區(qū)通常對應不同的數(shù)組,返回其元素個數(shù)來確定分區(qū)的行數(shù)
-
- break;
-
- case 1:
-
- return [dataArray2 count];
-
- break;
-
- default:
-
- return 0;
-
- break;
-
- }
-
- }
-
-
-
- //繪制Cell
-
- -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
-
-
-
- static NSString *CellIdentifier = @"Cell";
-
- //初始化cell并指定其類型,也可自定義cell
-
- UITableViewCell *cell = (UITableViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
-
- if(cell == nil)
-
- {
-
- cell = [[[UITableViewCellalloc]
-
- initWithFrame:CGRectZero
-
- reuseIdentifier:CellIdentifier] autorelease];
-
- }
-
- switch (indexPath.section) {
-
- case 0://對應各自的分區(qū)
-
- [[cell textLabel] setText:[dataArray1 objectAtIndex:indexPath.row]];//給cell添加數(shù)據(jù)
-
- break;
-
- case 1:
-
- [[cell textLabel] setText:[dataArray2 objectAtIndex:indexPath.row]];
-
- break;
-
- default:
-
- [[cell textLabel] setText:@"Unknown"];
-
- }
-
- return cell;//返回cell
-
- }
上面的例子在功能上介紹了tableview的使用,但其在數(shù)據(jù)處理上具有很大的局限性。當我們要從服務器上請求數(shù)據(jù),面對多種可能的數(shù)據(jù)(主要指數(shù)組的個數(shù)不穩(wěn)定)此時上面的switch將無法滿足我們的需求了。使用switch可是代碼的結(jié)構清晰明了,但其局限性很致命(switch中case的個數(shù)無法動態(tài)指定),下面的另一種方法可解決上述問題。

代碼在原由基礎上進行的修改:
- @interface TableViewTestViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>{
-
- UITableView *DataTable;
-
- NSMutableArray *dataArray1;
-
- NSMutableArray *dataArray2;
-
- NSMutableArray *titleArray;
-
- NSMutableArray *dataArray; //加入了用于保存數(shù)組的數(shù)組 dataArray
-
- }
-
-
-
- - (void)viewDidLoad
-
- {
-
- [superviewDidLoad];
-
- DataTable = [[UITableViewalloc] initWithFrame:CGRectMake(0, 0, 320, 420)];
-
- [DataTablesetDelegate:self];
-
- [DataTablesetDataSource:self];
-
- [self.viewaddSubview:DataTable];
-
-
-
- dataArray1 = [[NSMutableArrayalloc] initWithObjects:@"中國", @"美國", @"英國", nil];
-
- dataArray2 = [[NSMutableArrayalloc] initWithObjects:@"黃種人", @"黑種人", @"白種人", nil];
-
- titleArray = [[NSMutableArrayalloc] initWithObjects:@"國家", @"種族", nil];
-
- dataArray = [[NSMutableArrayalloc] initWithObjects:dataArray1, dataArray2, nil]; //初始化dataArray,元素為數(shù)組
-
-
-
- }
-
-
-
-
-
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
-
- {
-
- // Return YES for supported orientations
-
- return (interfaceOrientation == UIInterfaceOrientationPortrait);
-
- }
-
- //制定個性標題,這里通過UIview來設計標題,功能上豐富,變化多。
-
- - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
-
- UIView *view = [[[UIViewalloc] initWithFrame:CGRectMake(0, 0, 320, 40)] autorelease];
-
- [view setBackgroundColor:[UIColorbrownColor]];//改變標題的顏色,也可用圖片
-
- UILabel *label = [[UILabelalloc] initWithFrame:CGRectMake(5, 5, 100, 30)];
-
- label.textColor = [UIColorredColor];
-
- label.backgroundColor = [UIColorclearColor];
-
- label.text = [titleArrayobjectAtIndex:section];
-
- [view addSubview:label];
-
- return view;
-
- }
-
- //指定標題的高度
-
- - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
-
- return 40;
-
- }
-
-
-
- //每個section顯示的標題,有了上面的這個就不要了
-
- - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
-
- }
-
-
-
- //指定有多少個分區(qū)(Section),默認為1
-
- - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
-
- return [titleArraycount];
-
- }
-
-
-
- //指定每個分區(qū)中有多少行,默認為1
-
- - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
-
- /* switch (section) {
-
- case 0:
-
- return [dataArray1 count];
-
- break;
-
- case 1:
-
- return [dataArray2 count];
-
- break;
-
- default:
-
- return 0;
-
- break;
-
- }*/
-
- /* for(int i = 0; i < [titleArray count]; i++){
-
- if(section == i){
-
- return [[dataArray objectAtIndex:section] count];
-
- }
-
- }*/
-
- //上面的方法也是可行的,大家參考比較下
-
- return [[dataArray objectAtIndex:section] count]; //取dataArray中的元素,并根據(jù)每個元素(數(shù)組)來判斷分區(qū)中的行數(shù)。
-
-
-
-
-
- }
-
-
-
- //繪制Cell
-
- -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
-
-
-
- static NSString *CellIdentifier = @"Cell";
-
-
-
- UITableViewCell *cell = (UITableViewCell*)[tableView
-
- dequeueReusableCellWithIdentifier:CellIdentifier];
-
- if(cell == nil)
-
- {
-
- cell = [[[UITableViewCellalloc]
-
- initWithFrame:CGRectZero
-
- reuseIdentifier:CellIdentifier] autorelease];
-
- }
-
-
-
- /*switch (indexPath.section) {
-
- case 0:
-
- [[cell textLabel]
-
- setText:[dataArray1 objectAtIndex:indexPath.row]];
-
- break;
-
- case 1:
-
- [[cell textLabel]
-
- setText:[dataArray2 objectAtIndex:indexPath.row]];
-
- break;
-
- default:
-
- [[cell textLabel]
-
- setText:@"Unknown"];
-
- }*/
-
- //上面的方法也可行,大家比較下。
-
- [[cell textLabel] setText:[[dataArrayobjectAtIndex:indexPath.section]objectAtIndex:indexPath.row]];
-
- //同上,取出dataArray中每個分區(qū)所對應的元素(數(shù)組),并通過其來取值。 (大家要有想像力, 復制代碼試試就明白了)
-
-
-
- return cell;
-
-
-
- }
-
-
-
- //改變行的高度
-
- - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
-
- return40;
-
- }
轉(zhuǎn)自:http://www.cnblogs.com/top5/archive/2012/05/17/2506604.html
這篇學習的主要內(nèi)容是Multiview,在我們學習iphone旋轉(zhuǎn)的時候,介紹過多個view的使用方法,不過這里的view和旋轉(zhuǎn)屏幕中所指的多個view是不同的,旋轉(zhuǎn)屏幕中涉及到的多個view是在一個xib文件中的,而我們這里所指的mulitview,則是指多個xib,在多個xib中進行view的切換,也就是從一個xib切換到另一個xib,而每個xib中只有一個view。
另外的一個不同點體現(xiàn)在創(chuàng)建項目的時候,到目前為止,我們創(chuàng)建的所有項目的template都是single view,這次創(chuàng)建的項目將使用新的template。
Multiview applicatin的基本架構,一般來說,一個multiview application會有一個主要的controller來控制view的呈現(xiàn),這個主要的controller可以是toolbar(iphone上的Safari打開后,地下的一排按鈕就是toolbar)或者是tab bar(iphone打開phone,最下面一個一個的tab),或者其他的一些控件,他們控制到底那個view應該顯示,那個view應該被隱藏,也就是說,至少需要3個view才能實現(xiàn)view的切換,一個主要的controller view,2個其他的用于切換的view,主要的controller view是一直顯示在屏幕上的,而其他的view中,只有1個會顯示出來,其他的都被隱藏。ok,下面開始一步一步實現(xiàn)multiview吧,再說下去會越來越糊涂的。
0)項目簡介
今天要做的例子中包含3個view,一個controller view,我們會使用toolbar,2個用于切換的view,一個藍色底,一個黃色底,他們中間都有一個button,單擊button會有一個警告框彈出,告訴用戶當前顯示的是哪個view。
1)創(chuàng)建一個工程,選擇Empty Application

這次不再選擇Single View Application,而選擇Empty Application,項目中的所有文件我們都會手動進行添加。
單擊Next按鈕,之后的操作和創(chuàng)建Single View項目一樣,設定項目名稱“View Switcher”,設定項目保存路徑,項目創(chuàng)建完成。
2)添加View Controller
由于我們使用的模板是Empty Application,因此當創(chuàng)建完項目后,只有以下一些文件

里面并沒有我們需要的controller view,也沒有任何xib文件,這些都是需要我們手動添加的。使用快捷鍵command+N或者菜單欄File>New>New File...,在彈出的窗口中,左邊選擇Cocoa Touch,右邊選擇UIViewController subclass,點擊Next按鈕

填寫類名BIDSwitchViewController,其他都是默認選項(注意最后一個checkbox,如果選擇了,則將創(chuàng)建一個和BIDSwitchViewController關聯(lián)的xib文件,我們在這里可以選上,但是為了弄清楚view controller和xib文件是如何關聯(lián)在一起的,在這個項目中我們暫時不選,后面我們會手動連接這兩個文件),點擊Next按鈕。

選擇保持的位置,保存在“View Switcher”目錄下,完成創(chuàng)建。
BIDSwitchViewController是項目的最頂層的view controller(root controller),它用于控制另外2個view的切換,下面按照同樣的方法,創(chuàng)建另外2個view controller,一個名字教BIDBlueViewController,另一個叫做BIDYellowViewController,他們都不需要關聯(lián)xib,且都保存在“View Switcher”目錄下。創(chuàng)建完成后的“View Switcher”結(jié)構如下

3)添加xib文件
使用快捷鍵command+N或者菜單欄File>New>New File...,在彈出的窗口中,左邊選擇User Interface,右邊選擇View,點擊Next按鈕

Device Family中選擇iphone,點擊Next
命名為SwitchView.xib,同樣保持在“View Switcher”目錄下,點擊Create,完成創(chuàng)建。

使用同樣的方法創(chuàng)建另外兩個xib,分別命名為BlueView.xib和YellowView.xib。至此,我們所有的文件都已經(jīng)創(chuàng)建完畢,整個的“View Switcher”結(jié)構圖如下

接下來就是寫代碼的工作了。
4)編輯BIDAppDelegate文件
當一個app啟動的時候,我們都會默認的把一個view載入當前的iphone窗口(application's main window),在這個例子中,這個view就是我們的root view,即BIDSwitchViewController。我們是在BIDAppDelegate文件中設置默認載入的view的,因此首先打開BIDAppDelegate.h,添加class BIDSwitchViewController,和它的一個property,如下
#import <UIKit/UIKit.h> @class BIDSwitchViewController; @interface BIDAppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) BIDSwitchViewController *switchViewController; @end
其中,@class是告訴BIDAppDelegate,后面的BIDSwitchViewController是一個類,應該以類的方式處理該對象,后面在聲明property的時候,BIDAppDelegate就知道BIDSwitchViewController是一個類,不會不認該對象。
接著打開BIDAppDelegate.m,添加如下代碼
#import "BIDAppDelegate.h" #import "BIDSwitchViewController.h" @implementation BIDAppDelegate @synthesize window = _window; @synthesize switchViewController; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. self.switchViewController = [[BIDSwitchViewController alloc] initWithNibName:@"SwitchView" bundle:nil]; UIView *switchView = self.switchViewController.view; CGRect switchViewFrame = switchView.frame; switchViewFrame.origin.y += [UIApplication sharedApplication].statusBarFrame.size.height; switchView.frame = switchViewFrame; [self.window addSubview:switchView]; self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; return YES; } ......
首先import BIDSwitchViewController,然后聲明synthesize,對應于頭文件中的property。
didFinishLaunchingWithOption方法,當一個app載入完成后需要做一些什么事情,在這里,我們指定了哪個view被載入到windows中作為默認顯示的view。
self.switchViewController = [[BIDSwitchViewControlleralloc] initWithNibName:@"SwitchView" bundle:nil];
通過xib(在舊的版本中,xib被稱為nib,因此這里出現(xiàn)的是NibName)的名字來制定初始化哪個view
UIView *switchView = self.switchViewController.view;
獲取view
CGRect switchViewFrame = switchView.frame;
得到view的frame,也就是這個view的顯示位置,在前幾篇的文章中提到過這個屬性。
switchViewFrame.origin.y += [UIApplicationsharedApplication].statusBarFrame.size.height;
我覺得這句話比較重要,它將view的位置往下移動了20point(point在非retina屏幕中是20px,在retina屏幕中是40px),這樣就不會擋住iphone頂部的狀態(tài)欄了。
switchView.frame = switchViewFrame;
將修改過的frame從新賦值給switchView
[self.window addSubview:switchView];
將switchView設置成window的subview。怎么理解這句話呢,就是說,一個app只有一個窗口(window),這個window只能同時顯示一個view,且這個view是基于這個window而存在的,是放在這個window里面的,因此稱之為window的subview,子視圖。
5)編輯BIDSwitchViewController.h
BIDSwitchViewController是root controller,用于控制其他2個view的切換,因此需要在其頭文件中聲明其他兩個controller,然后需要定義一個Action,用來完成對2個view的切換,將BIDSwitchViewController.h修改成如下
#import <UIKit/UIKit.h> @class BIDBlueViewController; @class BIDYellowViewController; @interface BIDSwitchViewController : UIViewController @property (strong, nonatomic) BIDBlueViewController *blueViewController; @property (strong, nonatomic) BIDYellowViewController *yellowViewController; - (IBAction)switchViews:(id)sender; @end
代碼還是很好理解的,和前面在BIDAppDelegate.h中添加BIDSwitchViewController是一樣的。
6)關聯(lián)BIDSwitchViewController和SwitchView.xib
在Project Navigator中選中SwitchView.xib,在xib的dock中選中File's Owner

然后在Identity inspector中將Class改成BIDSwitchViewController

這樣就將SwitchView.xib關聯(lián)到了BIDSwitchViewController,如果我們選擇Connections inspector,會看到我們剛才在BIDSwitchViewController.h中定義的Action:switchViews出現(xiàn)在Received Actions,我們之后就可以將這個Action關聯(lián)到SwitchView.xib的控件上。
7)在SwitchView.xib上添加Toolbar
在這個例子總,我們切換veiw的方式是點擊Toolbar上的一個button,然后切換2個view,SwitchView.xib使我們的root view,因此我們需要在SwitchView.xib上添加一個toolbar,然后點擊toolbar上的按鈕,切換BlueView.xib和YellowView.xib。
選中SwitchView.xib,在object library中找到Toolbar

拖動到View上,放在最下方

默認的,已經(jīng)有一個button在Toolbar上了,雙擊button改變文字,將文字改成“Switch Views”

接著就是將“Switch Views”按鈕關聯(lián)到switchViews,選中“Switch Views”,control-dragged到File's Owner,在彈出的框中選中switchViews

打開Connections inspector,我們可以看到關聯(lián)后的情況

有一個不同的地方,Toolbar上的button不像一般的button,會有很多的方法讓你進行關聯(lián),Toolbar上button的Sent Actions(其他的button叫做Send Events,有很多個方法)只有一個方法,而它的作用相當于一般button的touch up inside。
8)關聯(lián)SwitchView.xib和BIDSwitchViewController's view outlet
BIDSwitchViewController繼承自UIViewController,在UIViewController中有一個outlet view,另外當我們在做第6)步的時候,將SwitchView.xib的class改成了BIDSwitchViewController,所以我們要將這個view關聯(lián)到SwitchView.xib,關聯(lián)的方法是選中SwitchView.xib,然后選中File's Owner,control-drag到下面的View

釋放鼠標后,在填出的框中選則view,這樣就關聯(lián)好了。

關聯(lián)好后,查看Connections inspector,也可以看到關聯(lián)后的結(jié)果

9)編輯BIDSwitchViewController.m
添加如下代碼
#import "BIDSwitchViewController.h" #import "BIDYellowViewController.h" #import "BIDBlueViewController.h" @implementation BIDSwitchViewController @synthesize yellowViewController; @synthesize blueViewController;
2個#import這個很好理解,因為BIDSwitchViewController是root controller,會控制另外2個controller,因此需要把另外2個controller引入進來,這樣才可以對他們進行操作。
2個synthesize對著頭文件中的2個property。
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. - (void)viewDidLoad { self.blueViewController = [[BIDBlueViewController alloc] initWithNibName:@"BlueView" bundle:nil]; [self.view insertSubview:self.blueViewController.view atIndex:0]; [super viewDidLoad]; }
首先去掉viewDidLoad的注釋,然后添加以上的代碼。從最后一句可以看出,viewDidLoad方法繼承自UIViewController,在這里對其重載,這個方法發(fā)生在當view已經(jīng)載入完成后,我們所要做的是當root view載入完成后,在載入root view的subview,在我們的這個例子中是BlueView。BlueView的載入方法和前面的一樣,使用initWithNibName,然后作為subView插入到當前的view中(當前的view就是root view,也就是SwitchView)。
- (IBAction)switchViews:(id)sender { if(self.yellowViewController.view.superview == nil) { if(self.yellowViewController == nil) { self.yellowViewController = [[BIDYellowViewController alloc] initWithNibName:@"YellowView" bundle:nil]; } [blueViewController.view removeFromSuperview]; [self.view insertSubview:self.yellowViewController.view atIndex:0]; } else { if (self.blueViewController ==nil) { self.blueViewController = [[BIDBlueViewController alloc] initWithNibName:@"BlueView" bundle:nil]; } [yellowViewController.view removeFromSuperview]; [self.view insertSubview:self.blueViewController.view atIndex:0]; } }
實現(xiàn)switchViews Action,上面的代碼還是很好理解的,首先判斷當前哪個subview是沒有superview的,因為這2個subview不會同時顯示,當blueSubview顯示時,YellowSubview就會從root view中移除,因此不會具有superview,當?shù)弥莻€subview沒有superview,就說明應該顯示這個subview。知道該顯示哪個subview后,再判斷這個subview是否還存在(是否需要重新載入初始化),然后將另一個subview從superview中移除,再將subview顯示出來。
- (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. if (self.blueViewController.view.superview == nil){ self.blueViewController = nil; } else { self.yellowViewController = nil; } }
當ios的內(nèi)存不夠用時,didReceiveMemoryWarning會被系統(tǒng)自動調(diào)用,來釋放可利用的內(nèi)存。在這里如果哪個subview沒有顯示,就釋放該subview,騰出內(nèi)存。
至此BIDSwitchViewController的所有代碼都寫好了,下面就應該處理BIDBlueVeiwController和BIDYellowViewController了。
(友情提示,時不時的編譯一下你的project,盡早發(fā)現(xiàn)問題,容易修改,否則到后面自己都不知道錯在哪里)
10)編輯BlueView.xib和YellowView.xib
分別在BlueView.xib和YellowView.xib上添加一個button,并命名為“Press me”。

修改BlueView.xib的class為BIDBlueViewController,修改YellowView.xib的class為BIDYellowController(修改方法:選中xib,點擊File's Owner,在Identity inspector中更改class)

class改變了,就需要重新關聯(lián)一下File's owner的view,方法和之前的一樣,選中File‘s Owner,control-drag到下面的View上,在彈出的框中選擇view,關聯(lián)完畢,2個xib都需要進行這個操作。
在Attributes inspector中,將BlueView.xib的background顏色改成藍色

同樣的方法將YellowView.xib的background顏色改成黃色

還有一個地方需要設置,因為我們是在root view中顯示這2個subview,而root view有一個toolbar在最下方,因此subview需要把toolbar的位置空出來,再進行自己的布局,還是打開Attributes inspector,在Simulated Metrics欄中有很多現(xiàn)象,他們都是用來模擬iphone屏幕上各種占位控件的,我們將Button Bar的選項設成Toolbar,這樣xib就會空出Toolbar的位置來進行布局計算了

仔細看的話,“Press me”按鈕的位置往上移動了那么一點點
11)在BIDBlueViewController和BIDYellowViewController中添加代碼
在BIDBlueViewController.h中添加Action,如下
@interface BIDBlueViewController : UIViewController - (IBAction)blueButtonPressed; @end
在BIDBlueViewController.m中實現(xiàn)blueButtonPressed,如下
- (IBAction)blueButtonPressed { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Blue View Button Pressed" message:@"You pressed the button on the blue view" delegate:nil cancelButtonTitle:@"Yep, I did" otherButtonTitles:nil]; [alert show]; }
在BIDYellowViewController.h添加Action,如下
@interface BIDYellowViewController : UIViewController - (IBAction)yellowButtonPressed; @end
在BIDYellowViewController.m中實現(xiàn)yellowButtonPressed,如下
- (IBAction)yellowButtonPressed { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Yellow View Button Pressed" message:@"You pressed the button on the yellow view" delegate:nil cancelButtonTitle:@"Yep, I did" otherButtonTitles:nil]; [alert show]; }
代碼都很簡單,就不多做解釋了。
12)關聯(lián)button和Action
打開BlueView.xib,選中“Press me”按鈕,control-drag到File's owner釋放,在填出的框中選擇blueButtonPressed。
打開YellowView.xib,選中“Press me”按鈕,control-drag到File's owner釋放,在填出的框中選擇yellowButtonPressed。
13)編譯運行
至此我們已經(jīng)可以編譯運行程序了,編譯成功后,iphone模擬器中顯示的效果(“Press me”按鈕的效果就不演示了)

按下“Switch Views”按鈕,BlueSubview會切換到Y(jié)ellowSubview

14)更炫的切換view的方法
有沒有發(fā)現(xiàn)上面切換view效果很無聊,ios中有更炫的切換view的方法,使用動畫的方式切換view,打開BIDSwitchViewController.m,重新編輯switchViews方法,如下
- (IBAction)switchViews:(id)sender { [UIView beginAnimations:@"View Flip" context:nil]; [UIView setAnimationDuration:1.25]; [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; if(self.yellowViewController.view.superview == nil) { if(self.yellowViewController == nil) { self.yellowViewController = [[BIDYellowViewController alloc] initWithNibName:@"YellowView" bundle:nil]; } [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES]; [blueViewController.view removeFromSuperview]; [self.view insertSubview:self.yellowViewController.view atIndex:0]; } else { if (self.blueViewController ==nil) { self.blueViewController = [[BIDBlueViewController alloc] initWithNibName:@"BlueView" bundle:nil]; } [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:YES]; [yellowViewController.view removeFromSuperview]; [self.view insertSubview:self.blueViewController.view atIndex:0]; } [UIView commitAnimations]; }
[UIViewbeginAnimations:@"View Flip" context:nil];
先可以不用理解這句話的意思,因為我也沒有理解,反正這行代碼是聲明一個animation block,前一個參數(shù)是設置animation block的title,后一個參數(shù)是設置一個對象,我也搞不清楚是干什么的,大概在以后的學習中會有所了解。
[UIViewsetAnimationDuration:1.25];
設定動畫時間,即切換view的時間
[UIViewsetAnimationCurve:UIViewAnimationCurveEaseInOut];
設定動畫的運動方式,開始慢,中間快,最后慢,大家開始看ios自己的說明吧。(An ease-in ease-out curve causes the animation to begin slowly, accelerate through the middle of its duration, and then slow again before completing. This is the default curve for most animations.)
[UIViewsetAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
設定切換的樣式,一共有4個值可以選:
UIViewAnimationTransitionFlipFromRight
UIViewAnimationTransitionFlipFromLeft
UIViewAnimationTransitionFlipCurUp
UIViewAnimationTransitionFlipCurDown
這個大家自試試就可以知道了
[UIViewcommitAnimations];
當所有動畫的值設置完畢后,提交動畫,之后view就會按照設定的動畫進行view的切換了。

(此圖截于書本,因此不同清晰)
15)總結(jié)
ok,所有的功能都已經(jīng)完成了,在這個例子中,我們使用toolbar來完成對不同view的切換,我們需要一個root view進行總的控制,然后多個subview進行切換,最后還使用一個比較炫的效果進行view之間的轉(zhuǎn)換,內(nèi)容很充實!
View Switcher
原文地址:http://www.cnblogs.com/minglz/archive/2012/12/11/2809368.html
在SQL語句優(yōu)化過程中,我們經(jīng)常會用到hint,現(xiàn)總結(jié)一下在SQL優(yōu)化過程中常見Oracle HINT的用法:1. /*+ALL_ROWS*/表明對語句塊選擇基于開銷的優(yōu)化方法,并獲得最佳吞吐量,使資源消耗最小化.例如:SELECT /*+ALL+_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';2. /*+FIRST_ROWS*/表明對語句塊選擇基于開銷的優(yōu)化方法,并獲得最佳響應時間,使資源消耗最小化.例如:SELECT /*+FIRST_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';3. /*+CHOOSE*/表明如果數(shù)據(jù)字典中有訪問表的統(tǒng)計信息,將基于開銷的優(yōu)化方法,并獲得最佳的吞吐量;表明如果數(shù)據(jù)字典中沒有訪問表的統(tǒng)計信息,將基于規(guī)則開銷的優(yōu)化方法;例如:SELECT /*+CHOOSE*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';4. /*+RULE*/表明對語句塊選擇基于規(guī)則的優(yōu)化方法.例如:SELECT /*+ RULE */ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';5. /*+FULL(TABLE)*/表明對表選擇全局掃描的方法.例如:SELECT /*+FULL(A)*/ EMP_NO,EMP_NAM FROM BSEMPMS A WHERE EMP_NO='SCOTT';6. /*+ROWID(TABLE)*/提示明確表明對指定表根據(jù)ROWID進行訪問.例如:SELECT /*+ROWID(BSEMPMS)*/ * FROM BSEMPMS WHERE ROWID>='AAAAAAAAAAAAAA'AND EMP_NO='SCOTT';7. /*+CLUSTER(TABLE)*/提示明確表明對指定表選擇簇掃描的訪問方法,它只對簇對象有效.例如:SELECT /*+CLUSTER */ BSEMPMS.EMP_NO,DPT_NO FROM BSEMPMS,BSDPTMSWHERE DPT_NO='TEC304' AND BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;8. /*+INDEX(TABLE INDEX_NAME)*/表明對表選擇索引的掃描方法.例如:SELECT /*+INDEX(BSEMPMS SEX_INDEX) USE SEX_INDEX BECAUSE THERE ARE FEWMALE BSEMPMS */ FROM BSEMPMS WHERE SEX='M';9. /*+INDEX_ASC(TABLE INDEX_NAME)*/表明對表選擇索引升序的掃描方法.例如:SELECT /*+INDEX_ASC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='SCOTT';10. /*+INDEX_COMBINE*/為指定表選擇位圖訪問路經(jīng),如果INDEX_COMBINE中沒有提供作為參數(shù)的索引,將選擇出位圖索引的布爾組合方式.例如:SELECT /*+INDEX_COMBINE(BSEMPMS SAL_BMI HIREDATE_BMI)*/ * FROM BSEMPMSWHERE SAL<5000000 AND HIREDATE<SYSDATE;11. /*+INDEX_JOIN(TABLE INDEX_NAME)*/提示明確命令優(yōu)化器使用索引作為訪問路徑.例如:SELECT /*+INDEX_JOIN(BSEMPMS SAL_HMI HIREDATE_BMI)*/ SAL,HIREDATEFROM BSEMPMS WHERE SAL<60000;12. /*+INDEX_DESC(TABLE INDEX_NAME)*/表明對表選擇索引降序的掃描方法.例如:SELECT /*+INDEX_DESC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='SCOTT';13. /*+INDEX_FFS(TABLE INDEX_NAME)*/對指定的表執(zhí)行快速全索引掃描,而不是全表掃描的辦法.例如:SELECT /*+INDEX_FFS(BSEMPMS IN_EMPNAM)*/ * FROM BSEMPMS WHERE DPT_NO='TEC305';14. /*+ADD_EQUAL TABLE INDEX_NAM1,INDEX_NAM2,...*/提示明確進行執(zhí)行規(guī)劃的選擇,將幾個單列索引的掃描合起來.例如:SELECT /*+INDEX_FFS(BSEMPMS IN_DPTNO,IN_EMPNO,IN_SEX)*/ * FROM BSEMPMS WHERE EMP_NO='SCOTT' AND DPT_NO='TDC306';15. /*+USE_CONCAT*/對查詢中的WHERE后面的OR條件進行轉(zhuǎn)換為UNION ALL的組合查詢.例如:SELECT /*+USE_CONCAT*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M';16. /*+NO_EXPAND*/對于WHERE后面的OR 或者IN-LIST的查詢語句,NO_EXPAND將阻止其基于優(yōu)化器對其進行擴展.例如:SELECT /*+NO_EXPAND*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M';17. /*+NOWRITE*/禁止對查詢塊的查詢重寫操作.18. /*+REWRITE*/可以將視圖作為參數(shù).19. /*+MERGE(TABLE)*/能夠?qū)σ晥D的各個查詢進行相應的合并.例如:SELECT /*+MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELET DPT_NO,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NOAND A.SAL>V.AVG_SAL;20. /*+NO_MERGE(TABLE)*/對于有可合并的視圖不再合并.例如:SELECT /*+NO_MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELECT DPT_NO,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO AND A.SAL>V.AVG_SAL;21. /*+ORDERED*/根據(jù)表出現(xiàn)在FROM中的順序,ORDERED使ORACLE依此順序?qū)ζ溥B接.例如:SELECT /*+ORDERED*/ A.COL1,B.COL2,C.COL3 FROM TABLE1 A,TABLE2 B,TABLE3 C WHERE A.COL1=B.COL1 AND B.COL1=C.COL1;22. /*+USE_NL(TABLE)*/將指定表與嵌套的連接的行源進行連接,并把指定表作為內(nèi)部表.例如:SELECT /*+ORDERED USE_NL(BSEMPMS)*/ BSDPTMS.DPT_NO,BSEMPMS.EMP_NO,BSEMPMS.EMP_NAM FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;23. /*+USE_MERGE(TABLE)*/將指定的表與其他行源通過合并排序連接方式連接起來.例如:SELECT /*+USE_MERGE(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;24. /*+USE_HASH(TABLE)*/將指定的表與其他行源通過哈希連接方式連接起來.例如:SELECT /*+USE_HASH(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;25. /*+DRIVING_SITE(TABLE)*/強制與ORACLE所選擇的位置不同的表進行查詢執(zhí)行.例如:SELECT /*+DRIVING_SITE(DEPT)*/ * FROM BSEMPMS,DEPT@BSDPTMS WHERE BSEMPMS.DPT_NO=DEPT.DPT_NO;26. /*+LEADING(TABLE)*/將指定的表作為連接次序中的首表.27. /*+CACHE(TABLE)*/當進行全表掃描時,CACHE提示能夠?qū)⒈淼臋z索塊放置在緩沖區(qū)緩存中最近最少列表LRU的最近使用端例如:SELECT /*+FULL(BSEMPMS) CAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;28. /*+NOCACHE(TABLE)*/當進行全表掃描時,CACHE提示能夠?qū)⒈淼臋z索塊放置在緩沖區(qū)緩存中最近最少列表LRU的最近使用端例如:SELECT /*+FULL(BSEMPMS) NOCAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;29. /*+APPEND*/直接插入到表的最后,可以提高速度.insert /*+append*/ into test1 select * from test4 ;30. /*+NOAPPEND*/通過在插入語句生存期內(nèi)停止并行模式來啟動常規(guī)插入.insert /*+noappend*/ into test1 select * from test4 ;
參考blog:http://blog.csdn.net/tianlesoftware/article/details/4969702
WordPress是一套很方便的個人部落格系統(tǒng)架設軟體,免費開放的原始碼,任何人都可以取得、修改、架設。但你知道嗎?其實WordPress除了個人部落格之外,其實還有另一個Project,就是「WordPress MU」。這個WordPress MU是多用戶的WordPress架設程式,架設成功的話就可以自己經(jīng)營BSP了,自己就像無名小站站長或是痞客邦這樣的部落格服務提供商,提供給有部落格需求的使用者使用。
雖然知道的人不多,但現(xiàn)在更棒的是這個WordPress MU從WordPress3.0版開始直接整合到WordPress之中,算是一項隱藏功能,需要透過一個代碼才能啟用這項服務,以往架設WordPress MU是要在額外架設,現(xiàn)在完全不用了,直接在自己本來的部落格系統(tǒng)內(nèi)就可以啟用WordPress MU,有興趣的話趕快來喚醒沉睡的WordPress MU吧!
目前全球最大的WordPress MU使用者就是WordPress.com這個免費的WordPress免費部落格服務,這個網(wǎng)站就是由WordPress MU系統(tǒng)建立的,如果把WordPress MU經(jīng)營的好當然就會像那樣囉!以往MU系統(tǒng)是額外獨立的專案,從3.0版的WordPress就把它整合進來,不再成為一個獨立的專案程式了,現(xiàn)在任何WordPress的使用者都可以把自己的網(wǎng)站改裝成WordPress MU。
WordPress MU被簡稱為「WPMU」,但全名其實是「WordPress Multi User」多用戶程式。這套程式之所以大家會很少聽到是因為對於一般使用者來說,用途其實不大,因為大家架設網(wǎng)站都是獨立架設、擁有自己的網(wǎng)站,很少有人和別人共用一個網(wǎng)址,利用他的子網(wǎng)域或是子資料夾架設獨立的WordPress。
那這套程式不就沒用了嗎?其實並不然。如果你有三五好友想要擁有一個部落格,但是不想要使用常見的BSP部落格,可是如果要自架,又不會改程式碼的話,又或是另一種情況,假若你有工作上的需要,需要架設多個WordPress,可是想要同一管理,這個WordPress MU就可以幫上忙了,因為他可以開通多個部落格,網(wǎng)站的設定統(tǒng)一由最大的管理者「超級管理」來處理,其他使用者只要負責使用就可以了,這樣一來對管理者來說管理輕鬆,對其他用戶來說也方便使用。
第1步 首先請您下載程式並進行WordPress的安裝,詳細安裝過程這邊不多做說明,如果不會安裝請參考:如何架設安裝WordPress部落格?,先將WordPress架設起來。當您的WordPress架設好後,請下載FTP內(nèi)的wp-config.php檔案,在檔案內(nèi)加入語法,避免加錯位置,可在「/* 設定完成,請儲存檔案。然後開始 Blogging 吧! */」之上加入,儲存後將檔案上傳到FTP中。
define('WP_ALLOW_MULTISITE', true);
![[教學]如何架設WordPress MU 多用戶部落格? [教學]如何架設WordPress MU 多用戶部落格?](http://img2.sofree.cc/2011/e666ff24b572_11DCE/wp_mu_0.png)
第2步 重新整理部落格後臺,點擊左方【工具】→「網(wǎng)誌網(wǎng)路」,進入後請將網(wǎng)誌網(wǎng)路的標題和聯(lián)絡信箱設定好,並點擊﹝安裝﹞。
[請注意]
如果您是從現(xiàn)有的部落格修改wp-config.php,想改裝成WordPress MU多用戶系統(tǒng),而非剛剛新架設的WordPress,那在子網(wǎng)域安裝部分無法設定,系統(tǒng)會強制您只能使用子目錄分類,來區(qū)分每個部落格。如果您是新架設的,那會出現(xiàn)子網(wǎng)域設定,請參考後面的教學說明。
錯誤訊息是:The main site in a sub-directory install will need to use a modified permalink structure, potentially breaking existing links.
![[教學]如何架設WordPress MU 多用戶部落格? [教學]如何架設WordPress MU 多用戶部落格?](http://img2.sofree.cc/2011/e666ff24b572_11DCE/wp_mu_1.png)
第3步 一旦設定好後,就無法再變更網(wǎng)站結(jié)構類型了。接著請按照畫面指示的訊息新增資料。
![[教學]如何架設WordPress MU 多用戶部落格? [教學]如何架設WordPress MU 多用戶部落格?](http://img2.sofree.cc/2011/e666ff24b572_11DCE/wp_mu_2.png)
第4步 請開啟FTP連上網(wǎng)站後在「/public_html/wp-content」目錄下新建一個資料夾「blogs.dir」並設定資料夾屬性為「777」,因為這邊是要儲存用戶上傳的檔案。
![[教學]如何架設WordPress MU 多用戶部落格? [教學]如何架設WordPress MU 多用戶部落格?](http://img2.sofree.cc/2011/e666ff24b572_11DCE/wp_mu_3.png)
第5步 接著請下載FTP根目錄中的「wp-config.php」請將WordPress後臺指示的資料加入倒wp-config.php的「/* 設定完成,請儲存檔案。然後開始 Blogging 吧! */」這句話之上,儲存然後上傳。
語法可能如下,但不完全一樣。
define('WP_ALLOW_MULTISITE', true); define( 'MULTISITE', true ); define( 'SUBDOMAIN_INSTALL', false ); $base = '/'; define( 'DOMAIN_CURRENT_SITE', 'wpblog.net.ru' ); define( 'PATH_CURRENT_SITE', '/' ); define( 'SITE_ID_CURRENT_SITE', 1 ); define( 'BLOG_ID_CURRENT_SITE', 1 );
![[教學]如何架設WordPress MU 多用戶部落格? [教學]如何架設WordPress MU 多用戶部落格?](http://img2.sofree.cc/2011/e666ff24b572_11DCE/wp_mu_4.png)
第6步 接著請再將FTP上的「.htaccess」檔案下載,並根據(jù)WordPress後臺指示的說明將資料加入到「.htaccess」檔案中,設定好後請上傳。
語法類似以下,但可能不完全一樣。
RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] # uploaded files RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-includes/ms-files.php?file=$2 [L] # add a trailing slash to /wp-admin RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L] RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L] RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L] RewriteRule . index.php [L]
![[教學]如何架設WordPress MU 多用戶部落格? [教學]如何架設WordPress MU 多用戶部落格?](http://img2.sofree.cc/2011/e666ff24b572_11DCE/wp_mu_5.png)
第7步 設定好後,請重新登入WordPress後臺,如果啟動成功進入後就會看到左上角會多出一個「超級管理」,這就是WordPress MU的管理選項,可以在那邊新增用戶、設定等等,因為升級成MU之後,原本的部落格也會屬於WordPress MU的一部分,所以在畫面中會多出限制用戶的儲存空間選項,預設都是10MB的儲存空間,使用者可以自己調(diào)整。
![[教學]如何架設WordPress MU 多用戶部落格? [教學]如何架設WordPress MU 多用戶部落格?](http://img2.sofree.cc/2011/e666ff24b572_11DCE/wp_mu_6.png)
第8步 點擊【超級管理】→﹝選項﹞可以對MU站點做設定,不過這有些部分的中文描述好像怪怪的,有點不通順就是了。設定上大家自己可以玩玩看囉!
![[教學]如何架設WordPress MU 多用戶部落格? [教學]如何架設WordPress MU 多用戶部落格?](http://img2.sofree.cc/2011/e666ff24b572_11DCE/wp_mu_7.png)
第9步 點擊【超級管理】中的「網(wǎng)誌」則可以建立新網(wǎng)誌,就是開一個獨立的部落格,開設在子資料夾內(nèi)。輸入您要的網(wǎng)站名稱在網(wǎng)誌位址以及網(wǎng)誌標題和該網(wǎng)誌站長的聯(lián)絡信箱就可以了,伺服器將會自動寄信通知部落格使用者。
![[教學]如何架設WordPress MU 多用戶部落格? [教學]如何架設WordPress MU 多用戶部落格?](http://img2.sofree.cc/2011/e666ff24b572_11DCE/wp_mu_8.png)
第10步 在網(wǎng)誌的清單中可以點擊您剛剛建立的部落格,點進去後可以對部落格做一些設定與調(diào)整,當然也可以保持預設不動作。
![[教學]如何架設WordPress MU 多用戶部落格? [教學]如何架設WordPress MU 多用戶部落格?](http://img2.sofree.cc/2011/e666ff24b572_11DCE/wp_mu_9.png)
第11步 建立好的部落格就像這樣子囉!
![[教學]如何架設WordPress MU 多用戶部落格? [教學]如何架設WordPress MU 多用戶部落格?](http://img2.sofree.cc/2011/e666ff24b572_11DCE/wp_mu_10.png)
WordPress MU 設定子網(wǎng)域
前面有提到,如果是新安裝的WordPress,那在您啟動WordPress MU功能同時,設定選項中會讓使用者選擇「子網(wǎng)域」或是「子目錄」。當然設定成子網(wǎng)域會比較好看,網(wǎng)址感覺高級一點,但相對的困難度也提高,因為需要動到系統(tǒng)設定檔案,目前網(wǎng)路上還沒有一個教學是針對「虛擬主機(Share Hosting)」,因為需要動到系統(tǒng)的阿帕契和DNS之類的設定,所以非常的麻煩。
第1步 如果是新架設的WordPress,在啟動MU功能時,會在【工具】→「網(wǎng)誌網(wǎng)路」中看見「子網(wǎng)域」和「子目錄」的設定,請您選擇子網(wǎng)域進行設定。請記住這邊一但選擇了網(wǎng)站架構,就不能進行更改,如果強制更改原始碼,可能會出現(xiàn)無法意料的錯誤。
![[教學]如何架設WordPress MU 多用戶部落格? [教學]如何架設WordPress MU 多用戶部落格?](http://img2.sofree.cc/2011/e666ff24b572_11DCE/wp_mu_11.png)
第2步 接著WordPress會偵測您的空間是否有辦法自動建立子網(wǎng)域,但在虛擬主機中,實驗的結(jié)果都是會失敗的,因為一般使用者沒有權限去調(diào)整伺服器的設定。以最常見的虛擬主機系統(tǒng)cPanel來說,用戶無法對其網(wǎng)址進行變更,必須由cPanel管理者透過WHM內(nèi)的DNS功能進行調(diào)整才行。如果您是自架主機,基本上應該就有權限可以設定,因此請先根據(jù)這頁面內(nèi)的資料把網(wǎng)站設定一下,這邊的設定就跟前面提到的部分是一樣的,因此就不多做說明。
![[教學]如何架設WordPress MU 多用戶部落格? [教學]如何架設WordPress MU 多用戶部落格?](http://img2.sofree.cc/2011/e666ff24b572_11DCE/wp_mu_12.png)
第3步 接著就是設定伺服器或虛擬主機以及網(wǎng)址部份了。關於虛擬主機要設定的「Wildcard DNS Record」等等之類的,以下有幾篇教學可以參考看看:這裡、這裡、這裡。如果虛擬主機支援的話,只要到DNS代管站新增一筆A紀錄,然後網(wǎng)域部分請輸入通用符號「*」,然後再輸入IP並新增就可以了。
大部分DNS代管站都可以,當然仍是有可能不支援的,目前測試的GoDaddy是可以新增前面提到所謂的「Wildcard DNS Record」資料。
You can create a wildcard A record by setting the Host Name value to “*" (asterisk). The wildcard causes the server to respond with the IP address specified instead of an error if the subdomain queried does not exist within your zone file.
![[教學]如何架設WordPress MU 多用戶部落格? [教學]如何架設WordPress MU 多用戶部落格?](http://img2.sofree.cc/2011/e666ff24b572_11DCE/wp_mu_dns.png)
第4步 設定好後,您可以自由的新增部落格,新增部落格的時候會發(fā)現(xiàn)網(wǎng)誌位址部分變成讓使用者輸入網(wǎng)域囉!
以下展示網(wǎng)站為殺氣測試,使用H-Sphere空間作為測試!
主網(wǎng)域部落格:http://tgcc.org.ru/
子網(wǎng)域部落格:http://happy.tgcc.org.ru/
![[教學]如何架設WordPress MU 多用戶部落格? [教學]如何架設WordPress MU 多用戶部落格?](http://img2.sofree.cc/2011/e666ff24b572_11DCE/wp_mu_13.png)
基本上設定就是這樣子而已,其實如果不使用子網(wǎng)域,一般虛擬主機都可以很輕鬆的啟用WordPress MU多用戶功能。不過有些人可能啟用會失敗,那就是主機不支援不支援固定網(wǎng)址的功能,您的Apache的「mod_rewrite」這個模組被禁用了,如果是個人用戶可以到系統(tǒng)檔案「httpd.conf」把分號去掉,如果是虛擬主機請聯(lián)絡管理員。
如果你本身沒有多用戶需求,建議不要啟動MU,因為啟動MU之後,部落格的資料庫會多一些資料表,每建立一個部落格,就會多出10多張的資料表。另外,啟動MU之後系統(tǒng)資源也會吃比較重,因為就等於在一個網(wǎng)站上架設好幾個部落格在運作,只是管理上比獨立架設方便,如果您有需要架設MU,最好要挑選一個限制比較少的虛擬主機來架設,否則三天兩頭資源就吃完了,空間被停是早晚的事情。
這兩天在全力設計東方設計圖庫頻道 期間嘗試了多種辦法來盡可能的與東方設計工作室主站集成在一起,起初嘗試了WordPress的Multisite功能,分別以Sub directory和Sub domain的形式分別各自試了一次,發(fā)覺,WP一旦開啟了Multisite以后結(jié)構變得復雜了很多,而且不夠穩(wěn)定,數(shù)據(jù)庫表也一下子飆升了很多,顯得非常臃腫,顯然這個并不是我所要的效果,于是經(jīng)過整個周末的來回嘗試,最后放棄了Multisite的形式,還是全新安裝了一個WP,經(jīng)過反復調(diào)試,已經(jīng)初具模型,但是問題就是用戶也得重新注冊一次,這個顯然再次違背了我的初衷,經(jīng)過反復Google,終于找到了一個完美的解決方案,那就是兩個完全獨立的WordPress共享同一個數(shù)據(jù)表,堪稱完美,不敢獨享,現(xiàn)將教程共享給各位。
因為圖庫站新建的WP已經(jīng)搭建出來了,而這個集成必須是后邊這個WP需要在共享前一個數(shù)據(jù)庫的用戶表的基礎上全新安裝才可以實現(xiàn),而且兩個WP必須建在同一個數(shù)據(jù)庫里邊,這個問題不大,只要改變一下前綴即可,于是說干就敢。
第一步、通過WP的工具》導出功能將已經(jīng)建立好的文章頁面等統(tǒng)統(tǒng)導出成一個XML文件;
第二步、修改新建的WP的配置文件wp-config.php如下所示:
$table_prefix = ‘blogb_’;
修改數(shù)據(jù)庫表前綴為新的前綴,防止和第一個WP沖突,然后在同個文件里找到
/* That’s all, stop editing! Happy blogging. */
在這斷話上方插入:
define(‘CUSTOM_USER_TABLE’, ‘wp_users’); define(‘CUSTOM_USER_META_TABLE’, ‘wp_usermeta’);
注意這里的wp_users和wp_usermeta都是第一個WP的用戶數(shù)據(jù)表,這里我們假設第一個WP用了默認的前綴;
第三步、修改完配置文件以后,就可以開始安裝第二個WP,安裝過程不是本教程討論的范疇,因此略過;
第四步、安裝完成你會發(fā)現(xiàn)可以直接用第一個WP網(wǎng)站的管理員直接登陸第二個WP網(wǎng)站后臺,然后進入工具》導入,將第一步導出的XML文件重新導入,然后進行一些必要的配置即可。
搞定收工,經(jīng)過測試非常完美,至此,在任意第一個或者第二個上新注冊的用戶,立馬可以直接用來登陸另外一個網(wǎng)站的后臺,F(xiàn)antastic,所謂踏破鐵鞋無覓處、得來全不費工夫,這幾天的忙活沒有白費,有了這個方法,理論上你可以設置任意多個獨立的WP系統(tǒng)共用同一個用戶數(shù)據(jù)表,有點類似于discuz的ucenter,但是這個顯然整合的更徹底,直接就是同一個表,不用擔心還需要再次同步的問題。
wordpress網(wǎng)站后臺登陸界面有個Logo圖標,在自己的網(wǎng)站擺著官方的圖標,很多人看起來很不舒服,所以大家都希望更換掉這個圖標,為此,小編推薦兩種wordpress更換圖標的方法:
準備一張命名為logo-login.gif的背景透明的圖片大小規(guī)格為310px*70px
在wordpress根目錄的wp-admin/images文件夾中找到logo-login.gif文件,
用這張圖片覆蓋替換為自己準備好的logo-login.gif圖片即可
訪問后臺登陸界面,圖標已更換。
優(yōu)點:簡單,快捷,適合新手使用;
缺點:更新升級版本時又得重新修改。
在主題函數(shù)文件functions.php中,添加如下一行,以修改鏈接地址:
add_filter(‘login_headerurl’, create_function(false,’return get_bloginfo(‘siteurl’);”));
在主題函數(shù)文件functions.php中,添加如下一行,以修改鏈接地址的標題提示:
add_filter(‘login_headertitle’, create_function(false,”return get_bloginfo(‘description’);”));
在主題函數(shù)文件functions.php中,添加如下內(nèi)容,以修改由CSS控制顯示的鏈接圖片:
function nowspark_login_head() { echo ‘<style type=”text/css”>body.login #login h1 a {background:url(http://www.mengzhiyi.info/wp-content/themes/mengzhiyi/images/buttom_logo.gif) no-repeat 0 0 transparent;height: 31px;width: 155px;padding:0;margin:0 auto 1em;}</style>’;}add_action(“login_head”, “nowspark_login_head”);//modify the background image
將url中鏈接修改為你自己的鏈接即可!
優(yōu)點:更新版本無需重新更改,更改圖片的同時把鏈接地址和標題提示也同時修改掉了;(本站推薦使用方法)
具體過程如下:
1、InstantRails-2.0安裝后,在配置環(huán)境變量path中配置ruby/bin目錄(如果系統(tǒng)中有多個RUBY,執(zhí)行命令行的時候系統(tǒng)認的就是path中的)
2、進入DOS命令行,執(zhí)行gem update --system,結(jié)果
Updating RubyGems...
ERROR: While executing gem ... (Gem::RemoteSourceException)
HTTP Response 302 fetching http://rubygems.org/yaml
這是因為gem的配置過低,無法進行遠程更新,執(zhí)行gem -v 發(fā)現(xiàn)是1.0.1
3、從下面這個地址下載 rubygems-update-1.3.7.gem,http://rubyforge.org/frs/download.php/70695/rubygems-update-1.3.7.gem
然后DOS命令進行該文件所在的目錄,執(zhí)行gem install --local rubygems-update-1.3.7.gem,出現(xiàn)信息
Successfully installed rubygems-update-1.3.7
1 gem installed
Installing ri documentation for rubygems-update-1.3.7...
Installing RDoc documentation for rubygems-update-1.3.7...
Could not find main page README
Could not find main page README
Could not find main page README
Could not find main page README
執(zhí)行gem -v查看,發(fā)現(xiàn)并沒有更新成功,Could not find main page README是什么意思我沒弄明白,但是我從http://production.s3.rubygems.org/yaml上發(fā)現(xiàn)這么一句
If you have an older version of RubyGems installed, then you can still
do it in two steps:
$ gem install rubygems-update # again, might need to be admin/root
$ update_rubygems # ... here too
我照著再執(zhí)行 update_rubygems,接著出現(xiàn)的信息很多,就不帖出來,再執(zhí)行gem -v,發(fā)現(xiàn)更新成功,已經(jīng)是1.3.7了
這一步是一切成功的源泉!!!!!!
4、接著再執(zhí)行gem update --system,提示
Updating RubyGems
Nothing to update
這是為什么我不明白,請高手指點一下
5、再執(zhí)行gem update rails --include-dependencies,提示信息
Updating installed gems
Updating rails
ERROR: Error installing rails:
actionpack requires rack (~> 1.0.0, runtime)
Gems updated: activesupport, activerecord
Installing ri documentation for activesupport-2.3.3...
Installing ri documentation for activerecord-2.3.3...
Installing RDoc documentation for activesupport-2.3.3...
Installing RDoc documentation for activerecord-2.3.3...
執(zhí)行rails -v,發(fā)現(xiàn)還是2.0.2沒有更新成功,根據(jù)actionpack requires rack (~> 1.0.0, runtime),應該是actionpack 需要1.0.0版本的rack
6、執(zhí)行gem install rack -v=1.0.0
Successfully installed rack-1.0.0
1 gem installed
Installing ri documentation for rack-1.0.0...
Installing RDoc documentation for rack-1.0.0...
更新成功
7、再次執(zhí)行 gem update rails --include-dependencies
出現(xiàn)信息
Updating installed gems
Updating rails
Successfully installed rake-0.8.7
Successfully installed activesupport-2.3.8
Successfully installed activerecord-2.3.8
Successfully installed rack-1.1.0
Successfully installed actionpack-2.3.8
Successfully installed actionmailer-2.3.8
Successfully installed activeresource-2.3.8
Successfully installed rails-2.3.8
Gems updated: rake, activesupport, activerecord, rack, actionpack, actionmailer, activeresource, rails
Installing ri documentation for rake-0.8.7...
Installing ri documentation for activesupport-2.3.8...
Installing ri documentation for activerecord-2.3.8...
Installing ri documentation for rack-1.1.0...
Installing ri documentation for actionpack-2.3.8...
Installing ri documentation for actionmailer-2.3.8...
Installing ri documentation for activeresource-2.3.8...
Installing ri documentation for rails-2.3.8...
Installing RDoc documentation for rake-0.8.7...
Installing RDoc documentation for activesupport-2.3.8...
Installing RDoc documentation for activerecord-2.3.8...
Installing RDoc documentation for rack-1.1.0...
Installing RDoc documentation for actionpack-2.3.8...
Installing RDoc documentation for actionmailer-2.3.8...
Installing RDoc documentation for activeresource-2.3.8...
Installing RDoc documentation for rails-2.3.8...
執(zhí)行rails -v,發(fā)現(xiàn)已更新成功
總結(jié):rails更新有兩種方式:1、聯(lián)機更新;2本地更新
聯(lián)機更新過程中如果出現(xiàn)HTTP Response 302 fetching http://rubygems.org/yaml無法更新,有兩種情況
一是gem的版本過低,二是與服務器的連接不通
此時可以試著加入其他服務器地址
gem source -l 查看列表
gem source -a http://rubygems.org 加入新的服務器地址
或者直接gem install rubygems-update --source http://rubygems.org
本地更新需要下載相應的gem包,版本需與要更新的rails版本對應,同時安裝順序有要求,因此gem包之間有依賴關系
順序從上面的顯示信息中可以看出來
Successfully installed rake-0.8.7
Successfully installed activesupport-2.3.8
Successfully installed activerecord-2.3.8
Successfully installed rack-1.1.0
Successfully installed actionpack-2.3.8
Successfully installed actionmailer-2.3.8
Successfully installed activeresource-2.3.8
Successfully installed rails-2.3.8
至于gem包的下載地址都在http://rubyforge.org/,但是有些項目的并不好找到,可以在google中直接搜索,就能找到在http://rubyforge.org/中的地址。
摘要: 作者: Aicken(李鳴) 來源: 博客園 發(fā)布時間: 2010-09-09 21:32 閱讀: 1021 次 原文鏈接 全屏閱讀 [收藏] 摘要:在這里我們將看到的是C#中利用ODP實現(xiàn)在Oracle數(shù)據(jù)庫中瞬間導入百萬...
閱讀全文
摘要: 我們要做到不但會寫SQL,還要做到寫出性能優(yōu)良的SQL,以下為筆者學習、摘錄、并匯總部分資料與大家分享! (1)選擇最有效率的表名順序(只在基于規(guī)則的優(yōu)化器中有效): ORACLE 的解析器按照從右到左的順序處理FROM子句中的表名,F(xiàn)ROM子句中寫在最后的表(基礎表 driving table)將被最先處理,在FROM子句中包含多個表的情況下,你必須選擇記錄條數(shù)最少的表作為基...
閱讀全文