forecho 的独立博客

把生命浪费在美好的事物上

iOS开发实例(四)- 用户界面(中)

2012年11月20日

接着上一篇文章。这一篇文章主要讲滑块功能。 一、添加滑块和标签,达到下图效果:     ** 1、打开.xib文件直接在IB库里面拖过来SliderLabel控件,然后改动位置以及长度。 ** 2、改动Slider属性参数:Value的Maximum改为100(即最大值为100),Current改为50(即默认值为50),如下图: 3、改Label的Text为100,然后依次选择Editor->Size to Fit Content,这样滑块大小正好包容“100”的字符长度。 二、实现滑块功能: 1、按住control拖动Slider控件到.h文件,创建一个操作:将Connection改为Action,name输入sliderChanged,然后回车,如下图: 2、按住control拖动Lable控件到.h文件,创建一个输出口:在name处输入sliderLable,然后回车,如下图: 3、在.m文件找到空的sliderChanged方法,添加代码,变成如下代码:

- (IBAction)sliderChanged:(id)sender {
    UISlider *slider = (UISlider *)sender;//将sender赋给一个UISlider指针
    int progressAsInt = (int)roundf(slider.value);//获取滑块的当前值,四舍五入为整数。然后赋值给整型变量
    sliderLabel.text = [NSString stringWithFormat:@"%d",progressAsInt];//创建一个字符串,使其包含该数值,并把字符串赋给标签
}

现在我们Run一下,如果你滑动滑块,左边的数字也在变化,那就证明你成功了。

iOS开发实例(四)- 用户界面(上)

2012年11月18日

这次要完成的效果图如下: 一、创建一个名为Control Fun的项目,选择的依旧的Single View Application模板。 二、用Photoshop做一张宽度小于300px高度小于100px的图片,此处我们使用的是(172px*80px),下图文件: 然后把图片直接拖到我们的Xcode项目中。记得在提示框中选中Copy items into destination group's folder(if needed)复选框。PS:我习惯性的把图片文件拖到Supporting Files文件夹下面。   三、根据上一节学到的知识,我们在BIDViewController.xib中制作出下图的效果来: 1、在IB中找到image View库,然后拖到视图中,刚拖过来时会自动全屏显示,然后需要我们手动调试大小,大致调的差不多就好了,然后在右边属性框找到Image View中,下拉选择我们需要的图片文件。(此处系统会自动识别图片文件)。 2、调整图片大小:有个最简单的方法,依次选择Editor->Size to Fit Content,那么Xcode会自动调试成图片原尺寸大小。 3、调整图片的位置:最简单的方法依次选择Editor->Align->Horizontal Conter in Container,Xcode会自动帮我们把图片放在视图中间位置。 4、接下来就是该设置图片属性了,下面是我总结的一张表(其实是Text文本库的属性,但是后面的属性跟图片是一样的): 此处基本上所以属性我们都不用该,只需要取消Drawing 下面的Clip SubviewsAutoresize Subviews这两个选项即可,因为此处我们根本不需要这两项。 5、在IB里面直接拖过来各俩个Text和Lable库,然后按照上上图布局即可。(小窍门:同时选中Lable的两个标签然后依次选择Editor->Align->Right Edges可以使两个标签文字右对齐)。 6、选中Text标签,然后根据自己的需要来选择或修改属性。(可以查看上图注释)此处我们在Placeholder添加了Type in a name;Capitalization 选择Words;Drawing选中Opaque取消Clears Graphics Context和Clip Subviews;Number的Text基本上和Name的Text一样,除了Placeholder添加了Type in a number;Capitalization保持默认,Keyboard选择Number Pad。   四、创建链接和输出口: 根据上一节学习的,按住control按键拖动Text到.h文件中,Name的Text在Name字段中填写nameField,Number的Text在Name字段中填写numberField,如下图: 此时我们可以Run一下我们的程序,得到如下结果即为成功:   五、关闭键盘 1、完成输入之后关闭键盘:只需在.h文件@end前加入如下代码即可:

- (IBAction)textFieldDoneEditing:(id)sender;

在.m文件中@end前加入如下代码:

- (IBAction)textFieldDoneEditing:(id)sender {
    [sender resignFirstResponder];
}

选中Name的Text,找到右边属性的最后一个图标,找到Did End ON Exit 将旁边那个圈拖到File's Owner,如下图,然后选择textFieldDoneEditing操作。 2、通过触摸背景关闭键盘:在.h文件@end前添加如下代码:

- (IBAction)backgroundTop:(id)sender;

在.m文件中@endq前加入如下代码:

-(IBAction)backgroundTop:(id)sender{
    [nameField resignFirstResponder];
    [numberField resignFirstResponder];
}

现在我们需要把View在右边属性中找到class从UIView改成UIControl,只有这样背景才能有触发操作。然后找到右边属性的最后一个图标,找到Tounch Down 将旁边那个圈拖到File's Owner,选择backgroundTop操作。   接下来我们Run一下,如果程序没有出问题的话,就能实现点击背景关闭键盘功能。   -———-上部分完,下部分请点击这里。

写个工作四个多月的总结

2012年11月16日

既然是4个月的工作总结,那么我就从4个月之前开始讲起吧。

4个多月前,也就是7月3号之前我在网上投了几份简历,也跑了几家面试,决定暂时还是留着武汉找工作了。然后4号的时候我就在上班了,在一家离我住处很近的办公楼上班,只要走十分钟就能到。公司很小,如果我没记错的话老板是万网的华中地区代理,反正以前在万网干过,然后现在自己单独搞了个外包公司,专门接网站做,公司包括老板的老婆一起还有2个销售,外加上我,3号面试的时候老板说过有程序员但是不在本地,说是去出差了,不知道真假。4号一上班老板就给我个未完成的项目,让我改什么什么,那个公司是用ThinkPHP写项目的,由于以前没接触过,顿时倍感压力很大,一天下来我头都没敢抬,也不知道那两个销售女生长得怎么样?只知道她们不停的在打电话,然后重复着“这里是中国万网,请问你们需要做网站吗?”。其实老板人还不错,给我的感觉特别像我大学的一个老师。

但是中午的时候我接到另外一家公司的offer了,这事让我当时挺纠结的,这家公司给的工资还不错,但是要三个月的实习期,公司是做钢铁电子商务的一个平台网站,公司规模也还可以,比较正规,但是离我住处比较远,还好有一趟直达的公交,技术部苦逼的程序员就我一个外加一美工和一个技术主管。从个人长远发展和公司的氛围出发,4号的那晚上我最终还是做出了一个决定,决定去比较远的公司上班了,也就是我现在的这个公司,那边的公司老板我直接没给回复了,有点坑那个老板了,只能不好意思了。

这也是没办法的事,这个世界从来没有任何一件工作叫“钱多、事少、离家近”。

那么在这个公司上班也有4个多月了,除了每天早出晚归外加上班挤不上电梯外其他的都还算可以,还好每天上下班的那个公交车不是很挤,我差不多都是从始点站到终点站,可以坐着看看书看看视频什么的,还算可以,唯一有点坑爹的就是这个公交车很难等,很长时间才来一趟。

那么这个公司的情况是目前有一个网站,算是比较大型的,那么我的任务就是维护这个网站,还有就是改版、升级这个网站,然后就是修复bug,平常也有市场部接到的企业网站,我们也要帮忙做一下单子。公司网站是外包给别人做的,用的是PHP最好的框架之一Yii开发的。那么我去上班的时候跟他们的合同还有一个月,后期的维护什么的只能靠我们了。

Yii这个框架真心很不错,但是入门很不容易,到现在我都不敢说我会Yii了,公司的网站我只能改改代码,要在自己写的话可能还是有难度的。四个月以来公司没事的话,我就看看视频然后自己多写写Yii的demo,准备先做个企业站开始,说实话刚开始的时候很勤快,现在有点慢了。但是还在进行中,我的目标是离开这个公司前务必把Yii学会,公司网站本身就是个很好的学习机会。

到新的公司刚开始是非常忙的,由于之前也没有接触Yii,然后主管要改个东西我都不知道如何下手,所以刚开始拼命的去Google资料,看了一些入门的文章,看了几个视频,还好有学过CodeIgniter框架,有MVC的基础,所以学起来还算可以,在改版网站的时候遇到过很棘手的问题,但都被我解决了,其实有些问题并没有我们想象中的那么难,只要你去动手做。

有段时间我一直觉得自己工资好低,待遇不平等,眼热比我晚出来工作搞iOS开发的同学工资比我高,所有很果断的买了个MacBook准备也要学iOS开发的,索性那个时候有条件,能借到钱,弟弟又准备买笔记本,于是我想到这可能是时候了。然后就在9月9号的时候我买了15寸的MacBook Pro,然后我的SONY笔记本现在就在我弟那了。前一段时间还在网上话了大几十块钱买了本《iOS5基础教程》,还给自己定了个年底的计划,眼看时间就要到了,我学的好慢呀。(没办法,只能晚上回去之后才有时间用MacBook,然后照着书写写代码。)现在想想MacBook那个时候一直都是我最想买的笔记本,非常想用MacBook做开发,想过会买,但是真的不知道什么时候能买到,后来了解到其实MacBook也并没有想象中的距我那么的遥远。

一个多月前(也就是十一国庆节回来),我就顺利的转正了,前个星期(11月11号)的时候去参加知乎的第二次聚会,无意中看到一位知友的电子书(nook2)看到那个屏幕真的很棒,然后回来的时候鉴于自己长工资了,想给自己一个转正的礼物,然后就在11月12号的时候果断的买了个Kindle 4黑色版,果然还不错,推送功能很给力,一口气下载了好多书,又得抽时间看书。时间啊时间。 说实话,刚开始我是准备在这个公司做到过年的,然后明年准备去一线城市的,但是呢?最近我的这个想法有点动摇了,特别是昨天开会老板说的一些话。老板是个30出头的人,个子虽然不高,但是给我的感觉是个很不错老板,每次给我们开会我感觉我都能学到点什么,虽然我们私底下从未有过交流。老板说,

刚开始找工作3年内不要跟公司谈待遇的事,因为你没什么资本,等你有了资本再谈也不迟,也许你觉得这个公司给我待遇不好,那么我跳槽,那个公司老板不好,那么我跳槽,其实你刚刚出来工作挑来挑去工作基本上都是大同小异,遇到的老板也是大同小异,还不如踏踏实实的干好自己的工作。

那些成功的人无非都是情商很高外加一点运气,(所以要学会培养自己的情商),而那些智商很高的人一般都是在给他们打工。

我在这家公司还有很多要学习的,不只是技术。我想如果公司没有我要学的东西了,那么就是我离开这个公司的时候了。

Yii自定义下拉菜单

2012年11月06日

有时候我们需要自定义下来菜单,如果数据是从数据库的另外一张表读取的话,你可以参考我的这篇文章。 但是现在我们只是要简单的做个下拉菜单,数据并不需要从数据库读取,自己定义即可,那么怎么样修改呢?其实也很简单,找到相应view文件夹下面的_form.php文件,找到下面这行代码:

<?php echo $form->textField($model,'type'); ?>

修改成:

<?php echo $form->dropDownList( $model,'type', array('0' => '菜单分类', '1' => '单页面'));?>

这时候页面生成的是如下HTML:

<select name="Category[type]" id="Category_type">
    <option value="0">菜单分类</option>
    <option value="1">单页面</option>
</select>

Yii修改默认分页每页显示条数

2012年11月06日

yii自带默认分页是每页显示10条信息。 如果要修改每页显示条数,我们先找到这个页面的相应的Models文件,找到search这个方法,然后找到下面这块代码:

return new CActiveDataProvider($this, array(
    'criteria'=>$criteria,
));

改成:

return new CActiveDataProvider($this, array(
    'criteria'=>$criteria,
    'pagination'=>array(
        'pageSize'=>2, //代表每页显示2条信息
    ),
));

yii隐藏index.php而不隐藏admin.php的方法

2012年11月06日

之前我介绍过yii模块的使用,使用模块的方法可以帮我们实现前后台分离的工作,但是本人不是很喜欢这个方法,个人认为模块是用来扩展的。 于是我又使用单独的入口文件,具体可以参考这篇文章。 这个时候我又想隐藏掉前台URL中的index.php,于是在网上找了一些资料,整合了这篇文章。 但是现在问题出现了,安装那个办法确实把前台中的index.php隐藏掉了,但同时也隐藏掉了admin.php,于是进入后台的时候URL就乱套了。路径都有问题。 解决办法就是: 在protected/admin/config/main.php文件中加入下面一行代码:

$frontendArray=require($frontend.'/config/main.php');
unset($frontendArray['components']['urlManager']);//不隐藏后台URL中的admin.php

yii自定义URL

2012年11月05日

1、首先找到 protected/config/main.php配置文件。找到如下图代码块: 把urlManager整个的注释都取消掉。 2、添加两行代码,示例如下:

'urlManager'=>array(
            'urlFormat'=>'path',
            'showScriptName' => false,// 使用URL重写,去掉index.php 
            'urlSuffix' => '.html',//开启伪静态
            'rules'=>array(
                '<controller:\w+>/<id:\d+>'=>'<controller>/view',
                '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
                '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
            ),
        ),

3、需要在项目的更目录下创建.htaccess内容如下:

Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# otherwise forward it to index.php
RewriteRule . index.php

OK,这时候基本的需求已经满足了,下面我们要扩展一下 urlManager 有时候会根据项目的需求需要扩展url,那么这个时候我们只需要简单的在urlManager的rules里面扩展就OK了。示例代码如下:

array(
    'posts'=>'post/list',
    'post/<id:\d+>'=>'post/read',
    'post/<year:\d{4}>/<title>'=>'post/read',
)
  • 调用$this->createUrl(‘post/list’)生成/index.php/posts。第一个规则适用。
  • 调用$this->createUrl(‘post/read’,array(‘id’=>100))生成/index.php/post/100。第二个规则适用。
  • 调用$this->createUrl(‘post/read’,array(‘year’=>2008,’title’=>’a sample post’))生成/index.php/post/2008/a%20sample%20post。第三个规则适用。
  • 调用$this->createUrl(‘post/read’)产生/index.php/post/read。请注意,没有规则适用。

只要你愿意,任何时候都不算晚

2012年11月05日

琢磨着趁现在年轻多学点东西,想让自己变得果断一点,于是乎在8月26日以迅雷不及掩耳之势买下了一台Macbook Pro。

然后最近自己又买了本《iOS5基础教程》,看了一些,想从事iOS

开发之路。

在公司还是继续讲究YII框架,琢磨着今年年底之前能使用YII框架写出个完整的网站出来。

前一段时间看了一篇文章《同时学习多种编程语言其实很容易》,其实讲的还算是有道理。各种语言其实学到最后大多都差不多了,你更多要学的其实是怎么优化,怎么去设计数据库,怎么去处理并发,内存管理,缓存管理等等。

前一段时间把《送你一颗子弹》看完了,然后发现其实看书还是蛮有意思的,所以打算多看一些书,少刷微博,少刷空间,没劲。

最近疯狂的在找一些科幻的美剧看,比如说找到了《Touch》(触摸未来)、《Fringe》(迷离档案,其实我更喜欢叫它危机边缘),感觉着两部还不错,他们思维比中国的电视剧要开阔要多的多,我本身也是比较喜欢看科幻片的。

突然发现英语的阅读水平对于程序员来说非常重要,所以我有必要重视一下我的英语。

以上差不多就是我为明年去上海(或者北京)做准备了。其实学习这事任何时候都不算晚,只要你来了兴趣。

鉴于每个星期如果坚持写博客的话,只要坚持下来,1年以后你会发现写博客水平会有所提升,几年下来就会有质的提升,于是我就当真了,我信了。

Substr(),mb_substr()及mb_strcut的区别和用法

2012年11月01日

substr()函数可以分割文字,但要分割的文字如果包括中文字符往往会遇到问题,这时可以用mb_substr()/mb_strcut这个函数,mb_substr()/mb_strcut的用法与substr()相似,只是在mb_substr()/mb_strcut最后要加入多一个参数,以设定字符串的编码,但是一般的服务器都没打开php_mbstring.dll,需要在php.ini在把php_mbstring.dll打开。 举个例子:

1
2
3
<?php
    echo mb_substr('这样一来我的字符串就不会有乱码^_^', 0, 7, 'utf-8');
?>

输出:这样一来我的字

1
2
3
<?php
    echo mb_strcut('这样一来我的字符串就不会有乱码^_^', 0, 7, 'utf-8');
?>

输出:这样一

从上面的例子可以看出,mb_substr

是按字来切分字符,而mb_strcut是按字节来切分字符,但是都不会产生半个字符的现象……mbstring

函数的说明:

php的mbstring扩展模块提供了多字节字符的处理能力,平常最常用的就是用mbstring来切分多字节的中文字符,这样可以避免出现半个字符的情况,由于是php的扩展,它的性能也要比一些自定义的多字节切分函数要好上一些。

mbstring extension提供了几个功能类似的函数,mb_substr和mb_strcut,看看手册上对它们的解释。 mb_substr mb_substr() returns the portion of str specified by the start and length parameters. mb_substr() performs multi-byte safe substr() operation based on number of characters. Position is counted from the beginning of str. First character’s position is 0. Second character position is 1, and so on. mb_strcut mb_strcut() returns the portion of str specified by the start and length parameters. mb_strcut() performs equivalent operation as mb_substr() with different method. If start position is multi-byte character’s second byte or larger, it starts from first byte of multi-byte character. It subtracts string from str that is shorter than length AND character that is not part of multi-byte string or not being middle of shift sequence.

再举个例子,有一段文字, 分别用mb_substr和mb_strcut来做切分:

1
2
3
4
5
6
<?php
    $str = '我是一串比较长的中文-www.webjx.com';
    echo "mb_substr:" . mb_substr($str, 0, 6, 'utf-8');
    echo "<br>";
    echo "mb_strcut:" . mb_strcut($str, 0, 6, 'utf-8');
?>

输出结果如下:

1
2
mb_substr:我是一串比较
mb_strcut:我是

CI自定义分页类

2012年10月29日

之前我写过一篇文章,介绍了CI如何分页,请猛击~ 那么考虑到一个项目要分页的地方比较多,所以后来我们写了一个单独的分页类,这样一个项目的效率会大大提升。 1、首先,我们在  application / libraries /下面创建page.php(扩展分页类)文件,代码如下:

<?php

class Page
{ 
	protected $url;
	protected $total;
	protected $size;
	protected $segment;
	protected $CI;

	function __construct($value){

		$this->url=$value['url'];
		$this->size=$value['size'];
		$this->total=$value['total'];
		//$this->segment=$value['uri'];

		$this->CI=& get_instance();

		$this->CI->load->library('pagination');

	}

	function fy(){

		return $this->page();

	}

	protected function page(){

		$config['base_url']=base_url($this->url);
		$config['total_rows']=$this->total;
		$config['per_page']=$this->size;
		//$config['uri_segment']=$this->segment;
		//GET分页 传参
		$config['page_query_string'] = TRUE;

		$config['num_links']=3;
		$config['first_link']='首页';
		$config['last_link']='末页';
		$config['prev_link']='上一页';
		$config['next_link']='下一页';
		$config['cur_tag_open'] = ' <a class="current">'; // 当前页开始样式  
		$config['cur_tag_close'] = '</a>'; // 当前页结束样式  

//      $this->CI->load->library('pagination', $config);

		$this->CI->pagination->initialize($config);

		return $this->CI->pagination->create_links();

	}

}

?>

2、那分页类写好了,如何使用呢?在控制器里面 controllers / feadmin.php文件(此处要结合你自己的项目,feadmin.php是我的控制器文件名)。下面是我们文章列表的示例代码:

function postsList() {
		$data['posts'] = $this->fe_model->page('posts', 'feadmin/postsList?',  @$_GET['per_page'], 2, 'id desc','category','posts.category = category.cid ');
		//print_r($data['posts']);
		$data['category'] = $this->fe_model->selectCate();
		//$data['category1'] = $this->fe_model->selectFormWhere('category',);
		//print_r($data['category1']);
        $data['title_for_layout'] = '文章列表';

        $this->load->view('admin/postsView', $data);
    }

此处我使用的是CI** GET分页**方法,具体需要看你的项目是否需要,此处可参考手册开启GET翻页功能。 fe_model是我项目的模型文件,那么要实现翻页,还需要在模型中写下面的方法:

//分页
	function page($form, $url, $offset, $size, $order, $join, $joinArray){

		$fy['url'] = $url;
		$fy['total'] = $data['total'] = $this->fy_n($form);
		$fy['size'] = $data['size'] = $info['size'] = $size;
		//$fy['uri'] = $offset;
		$this->load->library('page', $fy);
		$data['fy'] = $this->page->fy();
		//print_r($data['fy']);
		//$info['start'] = $data['start'] = $this->uri->segment($offset, 0);
		$info['start'] = $data['start'] = $offset;
		$info['order'] = $order;
		$data['admin'] = $this->fy_info($form, $info, $join, $joinArray);

		return $data;

	}

	function fy_n($form){

		return $this->db->get($form)->num_rows();

	}

	function fy_info($form,$value,$join,$joinArray){

		$this->db->order_by($value['order']);
		$this->db->limit($value['size'],$value['start']);
		if($join != ""){
			$this->db->join($join,$joinArray);
		}
		return $this->db->get($form)->result();

	}

	function pageWhere($form, $url, $offset, $size, $where, $order, $join, $joinArray){

			$fy['url'] = $url;
			$fy['total'] = $data['total'] = $this->p_numWhere($form, $where);
			$fy['size'] = $data['size'] =$info['size'] = $size;
			//$fy['uri'] = $offset;
			$this->load->library('page', $fy);
			$data['fy'] = $this->page->fy();
			//print_r($data['fy']);
			//$info['start'] = $data['start'] = $this->uri->segment(offset, 0);
			$info['start'] = $data['start'] = $data['start'] = $offset;
			$info['order'] = $order;
			$data['admin'] = $this->fy_infoWhere($form, $where, $info, $join, $joinArray);

			return $data;

	}
	function p_numWhere($form, $where){

		if(isset($where['where'])){
			$this->db->where($where['where']);
		}
		if(isset($where['like'])){
			$this->db->like($where['like'])	;
		}

		return $this->db->get($form)->num_rows();

	}

	function fy_infoWhere($form, $where, $value, $join, $joinArray){

		if(isset($where['where'])){
			$this->db->where($where['where']);
		}
		if(isset($where['like'])){
			$this->db->like($where['like']);
		}

		$this->db->order_by($value['order']);
		$this->db->limit($value['size'],$value['start']);
		if($join != ""){
			$this->db->join($join,$joinArray);
		}

		return $this->db->get($form)->result();

	}

3、下面的视图文件的代码:

<tbody>
	<?php foreach ($posts['admin'] as $post):
		?>
	<tr>
		<td>
		  <input type="checkbox" name="checkbox[]" value="<?php echo $post->id; ?>" />
		</td>
		<td><a href="feadmin/posts/<?php echo $post->id;?>" title="修改文章"><?php echo $post->title;?></a></td>
		<td><a href="feadmin/postsSearch/?category=<?php echo $post->category;?>" title="查询“<?php echo $post->name;?>”分类"><?php echo $post->name;?></a></td>
		<!-- <td><?php //echo date('Y-m-d', strtotime($post->addtime));?></td> -->
		<td><?php echo $post->addtime;?></td>
		<td>
			<a href="feadmin/posts/<?php echo $post->id;?>" title="修改"><img src="resources/images/icons/pencil.png" alt="修改" /></a> 
			<?php if($post->type != 1){?>
				<a href="feadmin/postsDelete/<?php echo $post->id;?>" title="删除" onclick="return(confirm('确定删除?'))"><img src="resources/images/icons/cross.png" alt="删除" /></a> 
				<!-- <a href="#" title="Edit Meta"><img src="resources/images/icons/hammer_screwdriver.png" alt="Edit Meta" /></a> -->
			<?php }?>
		</td>
	</tr>
  <?php 
  endforeach;?>
</tbody>

翻页的按钮代码如下:

<div class="pagination">
	<?php echo $this->pagination->create_links(); ?>
</div>

此处值得注意的是   完整项目代码请参考这里~