加载中…
个人资料
刘晓飞
刘晓飞
  • 博客等级:
  • 博客积分:0
  • 博客访问:85,202
  • 关注人气:18
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
新浪微博
评论
加载中…
留言
加载中…
访客
加载中…
博文
(2016-11-24 09:49)

新博客地址:www.sdkgo.com

阅读  ┆ 评论  ┆ 转载 ┆ 收藏 
一、安装Apache

​yum install httpd #根据提示,输入Y安装即可成功安装 

​/etc/init.d/httpd start #启动Apache

chkconfig httpd on #设为开机启动

​/etc/init.d/httpd restart #重启Apache​

二、安装MySQL

1、安装MySQLyum install mysql mysql-server #询问是否要安装,输入Y即可自动安装,直到安装完成

​/etc/init.d/mysqld start #启动MySQL

​chkconfig mysqld on #设为开机启动

2、为root账户设置密码mysql_secure_installation回车,根据提示输入Y输入2次密码,回车根据提示一路输入Y

​最后出现:Thanks for using MySQL!MySql密码设置完成,

重新启动MySQL:/etc/init.d/mysqld restart #重启

​/etc/init.d/mysqld stop #停止

​/etc/init.d/mysqld start #启动​

三、安装PHP5

1、安装PHP5yum install php根据提示输入Y直到安装完成 

2、安装PHP组件,使 PHP5 支持 MySQL

​yum install php-mysql php-gd libjpeg* php-imap php-ldap php-odbc php-pear php-xml php-xmlrpc php-mbstring php-mcrypt php-bcmath php-mhash libmcrypt

这里选择以上安装包进行安装根据提示输入Y回车

/etc/init.d/mysqld restart #重启MySql

​/etc/init.d/httpd restart #重启Apche

FTP安装与配置​

1.安装vsftpd

yum install vsftpd

2.启动/重启/关闭vsftpd服务器

[root@localhost ftp]# /sbin/service vsftpd restart

Shutting down vsftpd: [ OK ]

Starting vsftpd for vsftpd: [ OK ] 

OK表示重启成功了.​

​最后:终端输入SSH root@ip 即可连接SSH。如果连接过一遍,那么需要删除掉之前的RSA信息。

​vi ~/.ssh/known_hosts


阅读  ┆ 评论  ┆ 转载 ┆ 收藏 
标签:

ios

iphone

it

代码

分享

-(IBAction) sendInAppSMS:(id) sender
{
    MFMessageComposeViewController *controller =
        [[[MFMessageComposeViewController alloc] init] autorelease];
    if([MFMessageComposeViewController canSendText])
    {
        controller.body = @"Hello from Mugunth";
        controller.recipients = [NSArray arrayWithObjects:
                @"12345678", @"87654321", nil];
        controller.messageComposeDelegate = self;
        [self presentModalViewController:controller animated:YES];
    }
}
阅读  ┆ 评论  ┆ 转载 ┆ 收藏 
标签:

杂谈

获得通讯录中联系人的所有属性  ,看代码:
ABAddressBookRef addressBook = ABAddressBookCreate();

    CFArrayRef results = ABAddressBookCopyArrayOfAllPeople(addressBook);
    
    for(int i = 0; i < CFArrayGetCount(results); i++)
    {
        ABRecordRef person = CFArrayGetValueAtIndex(results, i);
        //读取firstname
        NSString *personName = (NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
        if(personName != nil)
            textView.text = [textView.text stringByAppendingFormat:@"\n姓名:%@\n",personName];
        //读取lastname
        NSString *lastname = (NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty);
        if(lastname != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@\n",lastname];
        //读取middlename
        NSString *middlename = (NSString*)ABRecordCopyValue(person, kABPersonMiddleNameProperty);
        if(middlename != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@\n",middlename];
        //读取prefix前缀
        NSString *prefix = (NSString*)ABRecordCopyValue(person, kABPersonPrefixProperty);
        if(prefix != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@\n",prefix];
        //读取suffix后缀
        NSString *suffix = (NSString*)ABRecordCopyValue(person, kABPersonSuffixProperty);
        if(suffix != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@\n",suffix];
        //读取nickname呢称
        NSString *nickname = (NSString*)ABRecordCopyValue(person, kABPersonNicknameProperty);
        if(nickname != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@\n",nickname];
        //读取firstname拼音音标
        NSString *firstnamePhonetic = (NSString*)ABRecordCopyValue(person, kABPersonFirstNamePhoneticProperty);
        if(firstnamePhonetic != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@\n",firstnamePhonetic];
        //读取lastname拼音音标
        NSString *lastnamePhonetic = (NSString*)ABRecordCopyValue(person, kABPersonLastNamePhoneticProperty);
        if(lastnamePhonetic != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@\n",lastnamePhonetic];
        //读取middlename拼音音标
        NSString *middlenamePhonetic = (NSString*)ABRecordCopyValue(person, kABPersonMiddleNamePhoneticProperty);
        if(middlenamePhonetic != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@\n",middlenamePhonetic];
        //读取organization公司
        NSString *organization = (NSString*)ABRecordCopyValue(person, kABPersonOrganizationProperty);
        if(organization != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@\n",organization];
        //读取jobtitle工作
        NSString *jobtitle = (NSString*)ABRecordCopyValue(person, kABPersonJobTitleProperty);
        if(jobtitle != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@\n",jobtitle];
        //读取department部门
        NSString *department = (NSString*)ABRecordCopyValue(person, kABPersonDepartmentProperty);
        if(department != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@\n",department];
        //读取birthday生日
        NSDate *birthday = (NSDate*)ABRecordCopyValue(person, kABPersonBirthdayProperty);
        if(birthday != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@\n",birthday];
        //读取note备忘录
        NSString *note = (NSString*)ABRecordCopyValue(person, kABPersonNoteProperty);
        if(note != nil)
            textView.text = [textView.text stringByAppendingFormat:@"%@\n",note];
        //第一次添加该条记录的时间
        NSString *firstknow = (NSString*)ABRecordCopyValue(person, kABPersonCreationDateProperty);
        NSLog(@"第一次添加该条记录的时间%@\n",firstknow);
        //最后一次修改該条记录的时间
        NSString *lastknow = (NSString*)ABRecordCopyValue(person, kABPersonModificationDateProperty);
        NSLog(@"最后一次修改該条记录的时间%@\n",lastknow);
        
        //获取email多值
        ABMultiValueRef email = ABRecordCopyValue(person, kABPersonEmailProperty);
        int emailcount = ABMultiValueGetCount(email);    
        for (int x = 0; x < emailcount; x++)
        {
            //获取email Label
            NSString* emailLabel = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(email, x));
            //获取email值
            NSString* emailContent = (NSString*)ABMultiValueCopyValueAtIndex(email, x);
            textView.text = [textView.text stringByAppendingFormat:@"%@:%@\n",emailLabel,emailContent];
        }
        //读取地址多值
        ABMultiValueRef address = ABRecordCopyValue(person, kABPersonAddressProperty);
        int count = ABMultiValueGetCount(address);    
        
        for(int j = 0; j < count; j++)
        {
            //获取地址Label
            NSString* addressLabel = (NSString*)ABMultiValueCopyLabelAtIndex(address, j);
            textView.text = [textView.text stringByAppendingFormat:@"%@\n",addressLabel];
            //获取該label下的地址6属性
            NSDictionary* personaddress =(NSDictionary*) ABMultiValueCopyValueAtIndex(address, j);        
            NSString* country = [personaddress valueForKey:(NSString *)kABPersonAddressCountryKey];
            if(country != nil)
                textView.text = [textView.text stringByAppendingFormat:@"国家:%@\n",country];
            NSString* city = [personaddress valueForKey:(NSString *)kABPersonAddressCityKey];
            if(city != nil)
                textView.text = [textView.text stringByAppendingFormat:@"城市:%@\n",city];
            NSString* state = [personaddress valueForKey:(NSString *)kABPersonAddressStateKey];
            if(state != nil)
                textView.text = [textView.text stringByAppendingFormat:@"省:%@\n",state];
            NSString* street = [personaddress valueForKey:(NSString *)kABPersonAddressStreetKey];
            if(street != nil)
                textView.text = [textView.text stringByAppendingFormat:@"街道:%@\n",street];
            NSString* zip = [personaddress valueForKey:(NSString *)kABPersonAddressZIPKey];
            if(zip != nil)
                textView.text = [textView.text stringByAppendingFormat:@"邮编:%@\n",zip];    
            NSString* coutntrycode = [personaddress valueForKey:(NSString *)kABPersonAddressCountryCodeKey];
            if(coutntrycode != nil)
                textView.text = [textView.text stringByAppendingFormat:@"国家编号:%@\n",coutntrycode];    
        }
        
        //获取dates多值
        ABMultiValueRef dates = ABRecordCopyValue(person, kABPersonDateProperty);
        int datescount = ABMultiValueGetCount(dates);    
        for (int y = 0; y < datescount; y++)
        {
            //获取dates Label
            NSString* datesLabel = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(dates, y));
            //获取dates值
            NSString* datesContent = (NSString*)ABMultiValueCopyValueAtIndex(dates, y);
            textView.text = [textView.text stringByAppendingFormat:@"%@:%@\n",datesLabel,datesContent];
        }
        //获取kind值
        CFNumberRef recordType = ABRecordCopyValue(person, kABPersonKindProperty);
        if (recordType == kABPersonKindOrganization) {
            // it's a company
            NSLog(@"it's a company\n");
        } else {
            // it's a person, resource, or room
            NSLog(@"it's a person, resource, or room\n");
        }
        
        
        //获取IM多值
        ABMultiValueRef instantMessage = ABRecordCopyValue(person, kABPersonInstantMessageProperty);
        for (int l = 1; l < ABMultiValueGetCount(instantMessage); l++)
        {
            //获取IM Label
            NSString* instantMessageLabel = (NSString*)ABMultiValueCopyLabelAtIndex(instantMessage, l);
            textView.text = [textView.text stringByAppendingFormat:@"%@\n",instantMessageLabel];
            //获取該label下的2属性
            NSDictionary* instantMessageContent =(NSDictionary*) ABMultiValueCopyValueAtIndex(instantMessage, l);        
            NSString* username = [instantMessageContent valueForKey:(NSString *)kABPersonInstantMessageUsernameKey];
            if(username != nil)
                textView.text = [textView.text stringByAppendingFormat:@"username:%@\n",username];
            
            NSString* service = [instantMessageContent valueForKey:(NSString *)kABPersonInstantMessageServiceKey];
            if(service != nil)
                textView.text = [textView.text stringByAppendingFormat:@"service:%@\n",service];            
        }
        
        //读取电话多值
        ABMultiValueRef phone = ABRecordCopyValue(person, kABPersonPhoneProperty);
        for (int k = 0; k<ABMultiValueGetCount(phone); k++)
        {
            //获取电话Label
            NSString * personPhoneLabel = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(phone, k));
            //获取該Label下的电话值
            NSString * personPhone = (NSString*)ABMultiValueCopyValueAtIndex(phone, k);
                
            textView.text = [textView.text stringByAppendingFormat:@"%@:%@\n",personPhoneLabel,personPhone];
        }
        
        //获取URL多值
        ABMultiValueRef url = ABRecordCopyValue(person, kABPersonURLProperty);
        for (int m = 0; m < ABMultiValueGetCount(url); m++)
        {
            //获取电话Label
            NSString * urlLabel = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(url, m));
            //获取該Label下的电话值
            NSString * urlContent = (NSString*)ABMultiValueCopyValueAtIndex(url,m);
            
            textView.text = [textView.text stringByAppendingFormat:@"%@:%@\n",urlLabel,urlContent];
        }
        
        //读取照片
        NSData *image = (NSData*)ABPersonCopyImageData(person);
            

        UIImageView *myImage = [[UIImageView alloc] initWithFrame:CGRectMake(200, 0, 50, 50)];
        [myImage setImage:[UIImage imageWithData:image]];
        myImage.opaque = YES;
        [textView addSubview:myImage];
        

    
    }
    
    CFRelease(results);
    CFRelease(addressBook);
阅读  ┆ 评论  ┆ 转载 ┆ 收藏 
标签:

杂谈

UIWebView是iOS最常用的SDK之一,它有一个stringByEvaluatingJavaScriptFromString方法可以将javascript嵌入页面中,通过这个方法我们可以在iOS中与UIWebView中的网页元素交互。

stringByEvaluatingJavaScriptFromString

    使用stringByEvaluatingJavaScriptFromString方法,需要等UIWebView中的页面加载完成之后去调用。我们在界面上拖放一个UIWebView控件。在Load中将google mobile加载到这个控件中,代码如下:

- ( void )viewDidLoad
{
[super viewDidLoad];
webview.backgroundColor 
= [UIColor clearColor]; 
webview.scalesPageToFit 
= YES;
webview.
 delegate = self;
NSURL 
* url = [[NSURL alloc] initWithString: @" http://www.google.com.hk/m?gl=CN&hl=zh_CN&source=ihp " ];

NSURLRequest 
* request = [[NSURLRequest alloc] initWithURL:url];
[webview loadRequest:request]; 
}

我们在webViewDidFinishLoad方法中就可以通过javascript操作界面元素了。

1、获取当前页面的url。

- ( void )webViewDidFinishLoad:(UIWebView * )webView { 
NSString 
* currentURL = [webView stringByEvaluatingJavaScriptFromString: @" document.location.href " ];
}

2、获取页面title:

- ( void )webViewDidFinishLoad:(UIWebView * )webView { 
NSString 
* currentURL = [webView stringByEvaluatingJavaScriptFromString: @" document.location.href " ];

NSString 
* title = [webview stringByEvaluatingJavaScriptFromString: @" document.title " ]; 
}

3、修改界面元素的值。

NSString * js_result = [webView stringByEvaluatingJavaScriptFromString: @"document.getElementsByName('q')[0].value='朱祁林'; " ];

4、表单提交:

NSString * js_result2 = [webView stringByEvaluatingJavaScriptFromString: @" document.forms[0].submit(); "];

这样就实现了在google搜索关键字:“朱祁林”的功能。

5、插入js代码

上面的功能我们可以封装到一个js函数中,将这个函数插入到页面上执行,代码如下:

[webView stringByEvaluatingJavaScriptFromString: @" var script = document.createElement_x('script'); " 
" script.type = 'text/javascript'; " 
" script.text = \"function myFunction() { " 
" var field = document.getElementsByName('q')[0]; " 
" field.value='朱祁林'; " 
" document.forms[0].submit(); " 
" }\"; " 
" document.getElementsByTagName_r('head')[0].appendChild(script); " ]; 

[webView stringByEvaluatingJavaScriptFromString:
 @" myFunction(); " ];

看上面的代码:

a、首先通过js创建一个script的标签,type为'text/javascript'。

b、然后在这个标签中插入一段字符串,这段字符串就是一个函数:myFunction,这个函数实现google自动搜索关键字的功能。

c、然后使用stringByEvaluatingJavaScriptFromString执行myFunction函数。

阅读  ┆ 评论  ┆ 转载 ┆ 收藏 
标签:

杂谈

NSUserDefaults 是用于存储用户偏好设置的类
这个类有两个“陷阱”,不注意的话得费点时间
以Key-Value的形式存储,容易理解
synchronize函数
这个函数通常在设置Key-Value之后调用
功能是立即将之前设置的Key-Value写入磁盘
当然,这是推荐做法
不调这个函数,通常也不会有问题
类似与socket中的flush
主要是为了防止夜长梦多,程序突然崩溃啥的,导致数据没有及时保存
阅读  ┆ 评论  ┆ 转载 ┆ 收藏 
标签:

杂谈

我一般会采用以下值传递的方法:假设现在有viewA和viewB两个视图
viewA  -->  viewB
2类方法:
1)在viewB里做一个全局变量,然后通过在viewA中创建viewB,然后为viewB的全局变量赋值
2)采用NSNotificationCenter。在viewA中写入如下代码:

[[NSNotificationCenter defaultCenter] postNotificationName:@"myNotification" object:@"viewA来的消息:刘晓飞好帅!"];

然后在viewB中写入如下代码:showNotification方法需要自己来写,用来赋值

 

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showNotification:) name:@"myNotification" object:nil];

viewA-->viewB  -->  viewA

2种方法:

1)同上第二种方法

2)这种方法即是我今天主打的方法:

 

1、首先定义个一委托UIViewPassValueDelegate用来传递值


  1. @protocol UIViewPassValueDelegate  
  2. (void)passValue:(NSString *)value;  
  3. @end 

这个protocol 就是用来传递值

2、在窗口1的头文件里,声明delegate


  1. #import <UIKit/UIKit.h> 
  2. #import "UIViewPassValueDelegate.h"  
  3. @interface DelegateSampleViewController UIViewController <UIViewPassValueDelegate> 
  4. {  
  5.     UITextField *_value;  
  6. }  
  7. @property(nonatomic, retain) IBOutlet UITextField *value;  
  8. (IBAction)buttonClick:(id)sender;  
  9. @end 

并实现这个委托


  1. (void)passValue:(NSString *)value  
  2. {  
  3.   self.value.text value;  
  4.     NSLog(@"the get value is %@", value);  

button的Click方法,打开窗口2,并将窗口2的delegate实现方法指向窗口1。


  1. (IBAction)buttonClick:(id)sender  
  2. {  
  3.     ValueInputView *valueView [[ValueInputView alloc] initWithNibName:@"ValueInputView" bundle:[NSBundle mainBundle]];  
  4.     valueView.delegate self;  
  5.     [self setModalTransitionStyle:UIModalTransitionStyleCoverVertical];  
  6.     [self presentModalViewController:valueView animated:YES];  

第二个窗口的实现

.h 头文件


  1. #import <UIKit/UIKit.h> 
  2. #import "UIViewPassValueDelegate.h"  
  3.  
  4. @interface ValueInputView UIViewController {  
  5.  
  6.     NSObject<UIViewPassValueDelegate> delegate;  
  7.     UITextField *_value;  
  8. }  
  9. @property(nonatomic, retain)IBOutlet UITextField *value;  
  10. @property(nonatomic, retain) NSObject<UIViewPassValueDelegate> delegate;  
  11. (IBAction)buttonClick:(id)sender;  
  12. @end 

.m实现文件


  1. #import "ValueInputView.h"  
  2. @implementation ValueInputView  
  3. @synthesize delegate;  
  4. @synthesize value _value;  
  5. (void)dealloc {  
  6.     [self.value release];  
  7.     [super dealloc];  
  8. }  
  9.  
  10. (IBAction)buttonClick:(id)sender  
  11. {  
  12.     [delegate passValue:self.value.text];  
  13.     NSLog(@"self.value.text is%@", self.value.text);  
  14.     [self dismissModalViewControllerAnimated:YES];      
  15.      
  16. }  
  17. (void)didReceiveMemoryWarning {  
  18.     // Releases the view if it doesn't have superview.  
  19.     [super didReceiveMemoryWarning];  
  20.       
  21.     // Release any cached data, images, etc. that aren't in use.  
  22. }  
  23.  
  24. (void)viewDidUnload {  
  25.     [super viewDidUnload];  
  26.     // Release any retained subviews of the main view.  
  27.     // e.g. self.myOutlet nil;  
  28. }  
  29.  
  30.  
  31. @end 
阅读  ┆ 评论  ┆ 转载 ┆ 收藏 

接IOS官方代码研究一

4.ControlsViewController类

这个类的.h文件没有什么特殊的。

在.m文件中,注意下面的定义:

 

#define kSliderHeight7.0

#define kProgressIndicatorSize40.0


#define kUIProgressBarWidth160.0

#define kUIProgressBarHeight24.0


#define kViewTag1

这样的定义是必须,在编程规范中,原则上是不允许硬编码的,所有的常量都应该是使用宏定义的方式。如果是多个文件中都使用的常量,应该使用一个专门的头文件定义,如果只是在一个类中使用,就定义在这个类的.m文件中。

 

@interface ControlsViewController (forwardDeclarations)

- (void)tintAction:(id)sender;

@end

这里使用catalog技术对类进行扩展,这里不对catalog技术进行讲述,如果有可能,我会专门写一个Objective-C的教程。值得一提的是,上面的方式看似定义了类的一个私有的函数,其实不然,由于Objective-C的运行期特性,这个语言的类是没有私有函数的概念的。如果在外面调用这个函数,编译期会给出一个警告,但是在运行的时候,程序不会crash。4.1函数viewDidLoad

 

if ([UIStepperclass])

    {

        [self.dataSourceArrayaddObject:[NSDictionarydictionaryWithObjectsAndKeys:

                                @"UIStepper",kSectionTitleKey,

                                @"Stepper 1 to 10",kLabelKey,

                                @"ControlsViewController.m:\r-(UIStepper *)stepper",kSourceKey,

                                self.stepper,kViewKey,

                             nil]];

    }

这个代码是中的[UIStepper class]是判断是否有UIStepper这个类。由于UIStepper是iOS5.0中引入的,所以这里必须进行判断一下,注意,即使如此,这个工程在5.0以前的模拟器中也是不能运行的。

 

// provide tint coloring only if its available

    if ([sliderCtl respondsToSelector:@selector(minimumTrackTintColor)])

    {

       // add tint bar button

       UIBarButtonItem *tintButton = [[UIBarButtonItemalloc]initWithTitle:@"Tinted"

                                                                      style:UIBarButtonItemStyleBordered

                                                                     target:self

                                                                     action:@selector(tintAction:)];

       self.navigationItem.rightBarButtonItem = tintButton;

        [tintButton release];

    }

这里的[sliderCtl respondsToSelector:@selector(minimumTrackTintColor)]是判断类UISlider是否有函数minimumTrackTintColor,通用,这个函数也是5.0中引入的。代码

 

CGRect frame =CGRectMake(198.0, 12.0, 94.0, 27.0);

       switchCtl = [[UISwitchalloc]initWithFrame:frame];

        [switchCtladdTarget:selfaction:@selector(switchAction:)forControlEvents:UIControlEventValueChanged];

        

       // in case the parent view draws with a custom color or gradient, use a transparent color

       switchCtl.backgroundColor = [UIColorclearColor];

[switchCtlsetAccessibilityLabel:NSLocalizedString(@"StandardSwitch",@"")];

switchCtl.tag =kViewTag;

是生成一个UISwitch的实例,函数switchAction:是这个实例的在事件UIControlEventValueChanged的响应函数。

 

CGRect frame =CGRectMake(174.0, 12.0, 120.0,kSliderHeight);

       sliderCtl = [[UISlideralloc]initWithFrame:frame];

        [sliderCtladdTarget:selfaction:@selector(sliderAction:)forControlEvents:UIControlEventValueChanged];

        

       // in case the parent view draws with a custom color or gradient, use a transparent color

       sliderCtl.backgroundColor = [UIColorclearColor];

        

       sliderCtl.minimumValue = 0.0;

       sliderCtl.maximumValue = 100.0;

       sliderCtl.continuous =YES;

        sliderCtl.value = 50.0;


// Add an accessibility label that describes the slider.

[sliderCtlsetAccessibilityLabel:NSLocalizedString(@"StandardSlider",@"")];

sliderCtl.tag =kViewTag;

是生成一个UISlider的实例,下面的代码就不分析了,因为都是比较简单的。这里需要提醒的是,在生成的UIActivityIndicatorView实例后,必须调用函数startAnimating,不然这个指示控件,是不会开始转动的。
5.TextFieldController类
这个类里面基本上没有什么需要特别解释的,需要提醒的是在函数textFieldLeftView中,

 

UIImageView *image = [[UIImageViewalloc] initWithImage:[UIImageimageNamed:@"segment_check.png"]];

       textFieldLeftView.leftView = image;

        [image release];

textFieldLeftView.leftViewMode =UITextFieldViewModeAlways;

为text field加入一个位于左边的view,是显示一个图片,当然也可以显示任何其他的图片。

阅读  ┆ 评论  ┆ 转载 ┆ 收藏 
标签:

杂谈

关于导航模式的view controller,这个例子是一个很有用的。下面是对这个例子的详细分析。
1. MainViewController类

程序运行的第一个界面如下:


一般情况下,导航模式的工程模板会隐含生成一个table view controller,亦即导航的主view是一个tableview,当然这个不是必须的,如果你希望生成一个主view不是tableview的也是可以的,你必须自己使用代码写,本文的后面会提到这个。

在XCode4.2中,如果你希望生成导航模式的,是选择Master-Detail Application,在下一个界面选择为iphone生成的。在XCode4.2以前的版本是选择Navigation-based Application,这里是只有为iphone生成的,不能选择为ipad生成的。

上面的第一个界面的代码是在MainViewController.h中,如果你不知道这个是如何联系起来的,请看下图,具体细节不解释了,在前面的文章中有提到的。


每一个导航模式中的view隐含的有一个导航区,就是view的上部,这里有四个部分,分别是本导航页的右button,back button, title, 左button,其中左button的位置和back button是重叠的,在导航的第一个view上是没有back button的,后面的view缺省有back button,当然,你可以使用代码隐藏这个back button.在任何界面上,缺省都没有左button,右button,和title,你需要自己手动设置。

在主view上,我们可以看到,左button是通过xib加入的。右button是通过代码加入的。

确切的说,左右和back button都不是一个普通的button,是一个button item,简化过的。

我们先看看左button的响应函数。

 

- (IBAction)styleAction:(id)sender

{

UIActionSheet *styleAlert = [[UIActionSheetalloc] initWithTitle:@"Choose a UIBarStyle:"

delegate:selfcancelButtonTitle:@"Cancel"

destructiveButtonTitle:nil

otherButtonTitles:@"Default",

@"BlackOpaque",

@"BlackTranslucent",

nil,

nil];

// use the same style as the nav bar

styleAlert.actionSheetStyle =self.navigationController.navigationBar.barStyle;

[styleAlertshowInView:self.view];

[styleAlertrelease];

}

这里点中左button后的界面如下:



关于Action Sheet的用法这里不再分析,你可以参考我在UICatalog中的分析。这个是选择导航栏的样式,共有三种,你可以每一个选择一下试试。这里需要说明的地方是,Xcode会在

styleAlert.actionSheetStyle =self.navigationController.navigationBar.barStyle;

这一行上面给出一个warning 或者error(取决你的设置,但是都不影响程序的运行),因为action sheet的actionSheetStyle和导航的barStyle不是同一个定义,它们是不同的枚举类型,大家知道枚举都是从0开始编码的整数,而且都是有三种类型,所以可以直接使用等号,但是会有一个警告。
在action sheet 的响应函数

- (void)actionSheet:(UIActionSheet *)modalView clickedButtonAtIndex:(NSInteger)buttonIndex

中,我们需要注意的是类似这样的代码。

[UIApplicationsharedApplication].statusBarStyle =UIStatusBarStyleDefault;

这个代码是使系统状态栏的样式和导航具有相同的样式。下面我们开始分析viewDidLoad函数,

 

- (void)viewDidLoad

{

// Make the title of this page the same as the title of this app

self.title = [[[NSBundle mainBundle]infoDictionary] objectForKey:@"CFBundleName"];

上面的这行代码就是设置导航区的title,你可以自定义为一个view,这样可以放一个图片在上面。

 

self.menuList = [NSMutableArray array];

// We will lazily create our view controllers as the user requests them (at a later time),

// but for now we will encase each title an explanation text into a NSDictionary and add it to a mutable array.

// This dictionary will be used by our table view data source to populate the text in each cell.

//

// When it comes time to create the corresponding view controller we will replace each NSDictionary.

//

// If you want to add more pages, simply call "addObject" on "menuList"

// with an additional NSDictionary.  Note we use NSLocalizedString to load a localized version of its title.

   if (!pageNames)

{

pageNames = [[NSArrayalloc] initWithObjects:@"PageOne",@"PageTwo", @"PageThree",@"PageFour", @"PageFive",nil];

    }

这里注意很多人在使用initWithObjects初始化一个NSArray的时候,会和initWithObject搞混。没有s的表示使用一个指针初始化NSArray,初始化后,这个NSArray的实例只有一个数据,所以在调用没有s的函数的时候是不能以nil结束的,但是有s的就不一样了,哪怕只有一个数据,或者没有数据,必须使用一个nil结束。

 

for (NSString *pageName in pageNames)

{

[self.menuListaddObject:[NSMutableDictionarydictionaryWithObjectsAndKeys:

                            NSLocalizedString([pageName stringByAppendingString:@"Title"], @""), kTitleKey,

                            NSLocalizedString([pageName stringByAppendingString:@"Explain"], @""), kDetailKey,

                            nil]];

}

上面的代码使用了for in又叫for each循环,如果有问题,请参考objective-c部分的说明。上面的代码循环部分就不解释了,你可能看起来有一些吃力,请参考我前面的文章关于国际化的部分,然后打开Localizable.strings这个文件,你一目了然了。

 

 // Create a final modal view controller

UIButton* modalViewButton = [UIButtonbuttonWithType:UIButtonTypeInfoLight];

[modalViewButtonaddTarget:selfaction:@selector(modalViewAction:)forControlEvents:UIControlEventTouchUpInside];

上面生成一个UIButton的实例,作为导航区的右button使用。

 

UIBarButtonItem *modalBarButtonItem = [[UIBarButtonItemalloc] initWithCustomView:modalViewButton];

self.navigationItem.rightBarButtonItem = modalBarButtonItem;

[modalBarButtonItemrelease];

这里就是使用代码添加右button的方法,很简单,但是记得需要调用[modalBarButtonItem release]释放UIBarButtonItem的实例,你可能会问,为何不释放UIButton的实例,因为创建的方式不同,modalBarButtonItem是使用alloc的方式,表示你自己管理内存,modalViewButton使用buttonWithType的方式,没有调用alloc,所以不需要自己释放,其实它是在自动内存释放池中。

 

[self.myTableViewreloadData];

}

下面一个要分析的函数是

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

这个函数在table view上一行被点中的时候调用。

 

NSMutableDictionary *rowData = [self.menuListobjectAtIndex:indexPath.row];

UIViewController *targetViewController = [rowDataobjectForKey:kViewControllerKey];

if (!targetViewController)

{

       // The view controller has not been created yet, create it and set it to our menuList array

       NSString *viewControllerName = [[pageNamesobjectAtIndex:indexPath.row]stringByAppendingString:@"ViewController"];

得到目标viewcontroller的名称

 targetViewController = [[NSClassFromString(viewControllerName)alloc] initWithNibName:viewControllerNamebundle:nil];

这里是Objective-C的运行期(Run Time)的一个特性,你可以通过一个类名来生成一个类。

 

[rowData setValue:targetViewController forKey:kViewControllerKey];

        [targetViewControllerrelease];

    }

    [self.navigationControllerpushViewController:targetViewController animated:YES];

导航到某个view controller,导航是一个栈的方式,所以到下一级就是push的方式。最后分析的函数是

- (IBAction)modalViewAction:(id)sender

这个函数如下

 

if (self.myModalViewController == nil)

       self.myModalViewController = [[[ModalViewControlleralloc] initWithNibName:

NSStringFromClass([ModalViewControllerclass]) bundle:nil]autorelease];


[self.navigationControllerpresentModalViewController:self.myModalViewControlleranimated:YES];

presentModalViewController:animated:是使一个viewcontroller从下面升上来。2.PageOneViewController

 

- (void)viewDidLoad

{

// Add our custom add button as the nav bar's custom right view

UIBarButtonItem *addButton = [[[UIBarButtonItemalloc] initWithTitle:NSLocalizedString(@"AddTitle",@"")

 style:UIBarButtonItemStyleBordered

 target:self

 action:@selector(addAction:)]autorelease];

self.navigationItem.rightBarButtonItem = addButton;

加入一个右button

}

3.PageTwoViewContrller

 

- (void)viewDidLoad

{

// add our custom image button as the nav bar's custom right view

UIBarButtonItem *addButton = [[UIBarButtonItemalloc] initWithImage:[UIImageimageNamed:@"email.png"]

style:UIBarButtonItemStyleBorderedtarget:selfaction:@selector(action:)];

self.navigationItem.rightBarButtonItem = addButton;

[addButtonrelease];

加入一个右button,和第一个不同的是,使用一个png图片来作为button的显示内容。

}

4.PageThreeViewController

 

- (void)viewDidLoad

{

// "Segmented" control to the right

UISegmentedControl *segmentedControl = [[UISegmentedControlalloc] initWithItems:

[NSArrayarrayWithObjects:

[UIImageimageNamed:@"up.png"],

[UIImageimageNamed:@"down.png"],

nil]];

[segmentedControladdTarget:selfaction:@selector(segmentAction:)forControlEvents:UIControlEventValueChanged];

segmentedControl.frame =CGRectMake(0, 0, 90, kCustomButtonHeight);

segmentedControl.segmentedControlStyle =UISegmentedControlStyleBar;

segmentedControl.momentary =YES;

defaultTintColor = [segmentedControl.tintColorretain];

// keep track of this for later


UIBarButtonItem *segmentBarItem = [[UIBarButtonItemalloc] initWithCustomView:segmentedControl];

    [segmentedControlrelease];

    

self.navigationItem.rightBarButtonItem = segmentBarItem;

    [segmentBarItem release];

上面的代码初始化右button,使用一个segmented controller,这里有两个部分,使用两个图片。很有趣,有时候我们会加入两个button,但是这个代码更简洁。关于segmented controller不是本文分析的重点,你可以在UICatalog中看到。

}


- (void)viewWillAppear:(BOOL)animated

{

UISegmentedControl *segmentedControl = (UISegmentedControl *)self.navigationItem.rightBarButtonItem.customView;

// Before we show this view make sure the segmentedControl matches the nav bar style

if (self.navigationController.navigationBar.barStyle == UIBarStyleBlackTranslucent ||

self.navigationController.navigationBar.barStyle == UIBarStyleBlackOpaque)

segmentedControl.tintColor = [UIColordarkGrayColor];

else

segmentedControl.tintColor =defaultTintColor;

是的segmented controller的背景颜色合适。

}

5.PageFourViewController这个类使用的技术和上面一个相同,不再多说。
6. PageFiveViewController这个类使用的技术和上面一个相同,只有以下需要说明的。

 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

if (!(self = [superinitWithNibName:nibNameOrNil bundle:nibBundleOrNil]));

上面这个地方有一个编译问题,有两种方式解决,一个就是加入一个return nil;,另一个就是不是用if.

 

self.title =NSLocalizedString(@"PageFiveTitle",@"");

   self.navigationItem.prompt =NSLocalizedString(@"Please select the appropriate media type:",@"Page Five Prompt");

使得导航区变得更宽,多显示一个文本区。

returnself;

}

7.个性化标题栏假如我们有一个图片如下,并且图片的名字为1.png



那么我们如何使用这个图片,而不是一个简单的文本来显示在标题栏上那?
首先把图片加入工程,然后可把下面的代码加入到合适的地方。比如viewDidLoad函数中。

 

UIImageView *fancyImageTitleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"1.png"]];

self.navigationItem.titleView = fancyImageTitleView;

    

[fancyImageTitleView release];

8.使用代码生成一个导航模式的view controller.如果你使用xcode 4.2,你就会发现工程类型为master-detail application在为iphone生成的工程就是一个导航模式的,这里生成的方式已经发生改变,不是使用xib的方式,而是使用代码的方式,
代码如下:

 

tcMasterViewController *masterViewController = [[[tcMasterViewController alloc] initWithNibName:@"tcMasterViewController" bundle:nil] autorelease];

    self.navigationController = [[[UINavigationController alloc] initWithRootViewController:masterViewController] autorelease];

    self.window.rootViewController = self.navigationController;

 

 

阅读  ┆ 评论  ┆ 转载 ┆ 收藏 
标签:

杂谈

UITableView是很重要的一个View了,这个话题有点大,因此我这里只是简单的分析这个例子给我们提供的信息。关于其他的,我会放在中级或者高级话题里面讲述。

类SimpleTableViewAppDelegate

在这个类中,我们可以学到如何动态生成一个导航模式的viewcontroller,一个table view controller,并且把table view controller作为导航模式的第一个view controller.

RootViewController *rootViewController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain];

代码方式生成一个view controller的一个实例,注意这里没有xib文件。需要说明的是,table view可以加载在一个普通的view controller上,也可以通过继承一个UITableViewController的方式生成,这里使用后一种方式生成。并且初始化为不分组模式(UITableViewStylePlain)。

 

// Retrieve the array of known time zone names, then sort the array and pass it to the root view controller.

NSArray *timeZones = [NSTimeZoneknownTimeZoneNames];

取得所有系统支持的,时区相关的地址名称,以显示在table view上

rootViewController.timeZoneNames = [timeZonessortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

这里我们学到了一个排序的方式,通过调用NSArray的函数sortedArrayUsingSelector来排序, 这个函数的传入参数是一个函数,可以是系统提供的函数,也可以是我们自己定义的函数,这里调用定义在NSString中的函数localizedCaseInsensitiveCompare。这个函数实现字符串的大小写不敏感的比较方式

UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];

代码的方式生成一个导航模式的view controller。把上面的view controller的实例作为根view controller。
RootViewController

 

self.navigationController = aNavigationController;

[aNavigationControllerrelease];

[rootViewControllerrelease];

注意上面的内存管理,我们知道,Objective-C的重点有三个,一个是内存管理,二是内存管理,三还是内存管理。rootViewController所指向的内存在alloc的时候计数为1,在调用

UINavigationController *aNavigationController = [[UINavigationController alloc]initWithRootViewController:rootViewController];

的时候自动增1,所以这里必须release一次。aNavigationController是同样的方式,最好自己分析一下。

 

// Configure and display the window.

[windowaddSubview:[navigationControllerview]];

把导航模式的view加载在window上。
类RootViewController这个类继承自UITableViewController,为了方便起见,很多时候我们也可以这么做,但是这里有一个问题,就是table view会占满整个空间,我们没法动态更改这个view的大小,如果我们使用前面的一种方式,就可以指定table view在view controller上的大小。
一个table view在显示在界面上的时候,需要调用下面这些函数,因为table view需要知道自己相关的一些数据。这些函数定义在UITableViewDataSource这个protocol里面。
一个table view必须有一个数据源(实现UITableViewDataSource的协议),还可能有一个UITableViewDelegate,这个协议定义的函数是在table view有动作的时候被调用,比如选择某一行,编辑table view等等。

 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

// There is only one section.

return 1;

}

一个table view分为一个或多个节(section),每一节可以有多行(row)上面的这个函数就是返回这个table view有多少个节.这个函数不是必须实现的。如果你不实现,那么这个节数是1。

 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

// Return the number of time zone names.

return [timeZoneNamescount];

}

上面这个函数返回某一节中有多少行。传入参数就是节所在index。这个函数是必须实现的。

 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

staticNSString *MyIdentifier = @"MyIdentifier";

// Try to retrieve from the table view a now-unused cell with the given identifier.

UITableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier:MyIdentifier];

// If no cell is available, create a new one using the given identifier.

if (cell ==nil) {

// Use the default cell style.

cell = [[[UITableViewCellalloc] initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:MyIdentifier] autorelease];

}

上面这几行代码是这个函数一般情况下必须写的,这里牵涉到一个内存管理,cell重用的问题,这个我会放在高级话题中讲,如果你是初级,那么先这么记着就可以了

 

// Set up the cell.

NSString *timeZoneName = [timeZoneNamesobjectAtIndex:indexPath.row];

cell.textLabel.text = timeZoneName;

上面的代码更新cell上的文本。需要提到的是,如果你看到某些代码写的是cell.text = @"blabla....";这样的方式,那么这个代码是3.0以前生成的,这样的方式已经被废弃的,请不要使用。

 

return cell;

}

 

上面的这个函数是table view的数据源代理的重要函数,在显示每一节的每一行的时候都会调用这个函数。

阅读  ┆ 评论  ┆ 转载 ┆ 收藏 
  

新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

新浪公司 版权所有