开发的一些事2011中秋版

最近在开发一款叫 秘密 的iPhone应用,经验值涨了不少,也有了些感悟。

 从 UILabel 的垂直顶部对齐(Vertical Alignment to top)说起

UILabel文字内容对齐方式是垂直居中的。这对于要将内容控制在绝对位置上就比较头疼。但想到这种大众需求肯定网上有了不少解决方案,搜索后果然在此发现了一堆解决方案。

解决方法无非就是填充了文字后,计算文字高度,然后重新修改label的高度,达到让文字顶部对齐的效果。但为了这个小功能加几十行代码,甚至有人封装了个类来实现不免有些笨拙。继续浏览,发现个投票数不高的答案:

myLabel.lineBreakMode = UILineBreakModeClip;
myLabel.text = [displayString stringByAppendingString:"\n\n\n\n"];

非常一亮的方法,简单暴力有效,在内容后面插入几个换行将内容顶到头部。和大头说了这个事后皆对回复者非常佩服。时刻得保持着跳动的思维真是件困难的事情。

非完美主义

不久前我还对完美主义有着些褒奖的看法。上次因为我对公司目前比较混乱的节奏表达了些看法后高同学表示很生气,datou第二天给我们准备了个ppt 非完美主义。

里面有张很生动的照片:人民大会堂的天花板上繁星般的灯泡,这种情况下要保证每个灯泡能完美的运行是很高难度的事,选择忍受些灯泡无法发光而不影响大局是比较折中并可行的方法。

另一个场景,小明回家嚷着吃西瓜,可家里没有。若等买了西瓜再给小明吃,小明早哭完而蛋了。但如果仔细询问小明,会发现他是踢了足球后口渴想吃西瓜,然后我们就可以先提供水来满足这个主要需求,等有了西瓜后再完成次要需求。

所谓的中间状态就是跳出完美主义一步到位的误区,在故障下给出快速有效的解决最基本需求。方式这个在腾讯有个专有的名词。忘记了,姑且称呼为非完美主义。

一个真实案例,qq早期有段时间服务器压力过载,无法容纳众多用户,问如何解决。
我的回答是做成游戏的队列模式,排队等待进入。
正确答案是,每个电脑只允许登陆一个qq!

答案有点急转弯,但真理是得谨记真实环境下问题都得分析到源头才能找到个比较快速暴力的解决方法。

一些片段

-对iPad
xu老板说:我从来不知道iPad有长按图标排列和拖放功能,但是我女儿一下子就发现了。

-某新版电视剧
gao同学说:那些骂着新版各种垃圾的人,有多少人是抱着怀旧心理,忽略新版的好,却揪着新版里不给力的地方不放缅怀着老版本,痛骂糟蹋老版。

-车玻璃的雾气
今晚小雨,gao同学车上起了雾气,开着空调吹啊吹。这次我忍不住了,你车没去雾功能?gao同学表示不知情。我把空调面板上按钮挨个一按,突然车窗下吹出很大的风,把堆积在上面的杂物废纸都吹了起来….. gao说,我从来没看过说明书

-光子的秘密
光子来北京出差,发现也安装了秘密,逐抢过想把玩下却被立即抢了回去。原来这小子也发了不少秘密却不会设置密码!这么明显的设置密码功能却不会用,我开始犹豫下版本加个tips功能

未完待续

UITableView 离奇滚动到顶部的问题

你是否有过类似的经验,从一个TableView push到另一个视图后,然后pull back, 这时候有可能会发现tableView的contentOffset 已经滚动到顶部了,而且时有时无,所以也就没深入探讨下去了?

举个很简单的例子,现在有个附件位置聊天工具叫 陌陌, 我就喜欢在列表页面一直向下滑动找各种美女看PP,可是在看完美女资料返回列表后经常发现居然又滚回视图的顶部了,悲痛之余,又得话费很久时间重新滚动到下面,继续看美女。然后又被离奇的滚动到顶部。。。。

其实这个问题在 这篇文章 里提到过,没错还是 -viewDidUnload 导致的问题。首先我们来快速重现下这个bug

  1. 新建一个iOS项目,模板使用 Navigation-base App
  2. 在默认的tableViewController里
    1. - viewDidLoad 设置下 self.title=@”table”
    2. - numberOfRows 设置为 200 个cell
    3. 给每个cell添加点文字,当前的indexPath.row 的值就很好
    4. - didSelectRow 里随便push到个新的 ViewController
    5. - viewDidUnload 加个NSLog,方便跟踪消息
  3. 向下滚动些cell,然后点击进入第二个vc的视图
  4. 选择模拟器的菜单 Hardware->Simulate Memory warning , 你应该能在console里看到2行log,第二行log应该是来自于你的 -viewDidUnload  方法
  5. 返回tableView,你会发现bug重现,tableView的y偏移位已经变回0 !

其原因很容易解释,在接收到内存警报的通知后,非当前用户可见的视图控制器(vc)会接收到额外的通知,并将它的view给释放掉节约内存占用。然后当该vc的视图即将重新被用户可见时(比如被pullBack),vc会调用 -loadView , – viewDidLoad 这些方法重新将view创造出来, 但是偏移位却没有被保存下来,所以就发生这个Bug了。

写到这里应该已经知道如何解决这个问题了吧,增加一个变量记录来记录当前tableView.contentOffset.y 的数值,然后 – viewDidLoad 里面将tableview的偏移位给恢复即刻。

番外篇

iOS 中内存问题会导致各种奇怪的现象,在 – viewDidUnload被执行后会导致下次 – loadView, – viewDidLoad 被重新执行,所以一定要在 -viewDidUnload 中把其他retain的东西给释放掉。

每次通过模拟器的菜单来模拟内存警告比较麻烦,这里提供一个特殊的类来实现自动内存警报功能,将你的视图控制器从该类继承下来,这里以UIViewController为例子。当视图不可见时,该控制器便会自动接收到内存警告并释放掉自己的视图。这样子调试起来就方便了。有木有!!!

@interface MotherUIViewController : UIViewController
- (void)simulateMemoryWarning;
@end
@implementation MotherUIViewController
- (void)viewDidDisappear:(BOOL)animated{
	[super viewDidDisappear:animated];
	[self simulateMemoryWarning];
}
- (void)simulateMemoryWarning
{
#if TARGET_IPHONE_SIMULATOR
#ifdef DEBUG
	CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), (CFStringRef)@"UISimulatedMemoryWarningNotification", NULL, NULL, true);
#endif
#endif
}
@end

XCode4 文档中激活文档目录功能

在XCode3的文档中,我们可以方便的通过文档目录(Table of contents) 来迅速导航到需要的章节

但是在xcode4中,居然去掉了这么重要的功能,而仅仅在文档顶部有个蹩脚的导航功能。

以下是重点,一句话恢复toc

sudo egrep -lRZ "Prototype.Browser.Xcode4OrNewer=Prototype.Browser.XcodeVersion<1000;" /Library/Developer/Documentation/DocSets | xargs -0 -L % sudo sed -i '' -e 's/Prototype\.Browser\.Xcode4OrNewer\=Prototype\.Browser\.XcodeVersion\<1000\;/Prototype\.Browser\.Xcode4OrNewer\=false\;/g'

稍等片刻后目录便回来了,这下查阅文档方便不少。

源地址

[Rails]奇怪的 ArgumentError错误

昨天抄起丢了多年的Rails折腾一个后台界面。

在routes里添加了如下两个新的操作

namespace do |admin|
admin.resources :reports, :collection => {:single=>:get, :process=>:post}
end

然后用rake routes 看了下没问题后便继续开始实现控制器中对应的代码。
但是却始终无法执行对应的操作,却提示错误:

ArgumentError (wrong number of arguments (2 for 0)):

甚至连之前能正常运行的方法也无法访问。

各种纠结搜索尝试一个多小时后终于发现,原来这次又撞到rails的关键字上了 Process 居然是关键字!!
换了个名字后果断欢快的跑了起来。
完。

附上万恶的Rails+Ruby关键字列表地址(非常多,以后有诡异情况记得先来这边查查)

[iOS]UIActionSheet动态添加按钮

UIActionSheet 只提供了一个构造函数

- (id)initWithTitle:(NSString *)title delegate:(id&lt;UIActionSheetDelegate&gt;)delegate cancelButtonTitle:(NSString *)cancelButtonTitle destructiveButtonTitle:(NSString *)destructiveButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ...

如果需要动态的添加按钮,就必须使用另外个函数:

- (NSInteger)addButtonWithTitle:(NSString *)title;

但出现的诡异结果是新添加的内容均出现在 取消 按钮之下,非常讨厌。

解决方法直接看代码

//.....
    UIActionSheet* sheet = [[UIActionSheet alloc] initWithTitle:NSLocalizedString(@"请选择埋掉的原因", @"reason to bury")
                                                       delegate:self
                                              cancelButtonTitle:nil
                                         destructiveButtonTitle:nil
                                              otherButtonTitles:nil];
    [sheet addButtonWithTitle:@"btn1"];
    [sheet addButtonWithTitle:@"btn1"];
    [sheet addButtonWithTitle:@"btn1"];
    [sheet addButtonWithTitle:NSLocalizedString(@"取消", @"cancel button title")];
    sheet.cancelButtonIndex = sheet.numberOfButtons - 1;
//....

[技术贴]苹果如何制造排队

crowded_queue

最近iPad2上市居然再次掀起排队热潮,和之前相比更是越来越火热.昨天甚至发生了三里屯的打架事件,相传苹果店员直接干翻了4位黄牛,最后价值30w的大门也被群众摧毁,于是店长宣布三里屯再次停业.

网上有说苹果也学国内公司租人排队,但我觉得下文的分析更可靠些,开始揭开苹果的另一个阴谋:

大家都知道苹果产品每每发布就排队抢购的事情. 往年iPod发布也这样,只是现在大家都有了所以就不去挣了.
而这个排队现象如何形成的呢?

首先如果只有几个人去买肯定形成不了排队, 而在心理学上叫做 Lining 效应 , 排队效应 .
而这个就是一种人性的弱点, 好比你看一个饭馆排队 下意识认为这个饭馆菜一定好吃.

如果你看到有人打架 围观人越多你会觉得事情越大.
之所以看热闹不嫌事儿大的道理. 苹果也将这种心理战运用到产品营销上.

首先当苹果要发布产品的时候会用尽各方人马通知人来到店购买. 并且通过店面摄像头与数据分析得出目前排队长度.
一般内部流程将人们的等待时间控制到45分钟到47分钟, 这个时间段是经过科学分析和实验的. 这个时间属于人们等待耐心的一个高峰.

在国内如果商家看到门口排了队伍首先就是要加快收银速度因为很多地方都是客户已经拿到物品等待付款. 如果时间超过19分钟人们就到了烦躁周期的第一波 会有26.4%的购物者选择不付款直接离开.

所以苹果将购物流程改为让购买者先不要得到物品, 实行一手交钱一手交货的销售方式来发挥排队效应.
一般在Apple Store所有的员工都有一个快速结算系统, 就是不管你在哪苹果的工作人员都可以帮你刷卡支付无需到款台.

当苹果需要创造排队效应的时候, 苹果按照数学模型来分析人群然后将在结算桌面上得出一个结算的时间.

这结算时间就是告诉结算的员工您需要浪费多长时间来结算一个客户. 比如如果外面有1000人排队 ,
那苹果一般就只开1 到 3个收银台, 每个付款时间需要至少到 17分钟.

而一般结算时间只有55秒.

这样就造成了 货少难买现象, 而从人性弱点出发 , 越得不到的越好 , 越多人抢的越好 , 而人们也会计算时间成本, 就是已经排了47分钟 不在乎再排47分钟了.

而且当您付款后的时候 , 苹果一定会告诉您, 您终于拥有了您的xxxx产品, 只字不提我们已经拥有了你的钱的事情.

如这个事情搁小时候老人总给我说 把自己卖了还帮人数钱就是这个道理吧.

说得有点多 , 或许这套排队理论国内的厂商也可以在适当的时候运用一下 , 而不是花钱雇人来形成排队效果那是在是太没品味了.

路人甲:有感触 我也纳闷为啥每次就开这么俩款台 其他人都外面欢迎
坑爹啊

[声明,本文转载自这里]

Mac可以这么玩-用Finder示爱!

刚刚消灭reader数字时发现这篇非常有趣的文章(结果不小心点错地方将2w+未读一下清空为0了,google你有没有撤销的操作吖!!!)

原文来自 tuaw

何止有爱,每个mac用户都会自问,我用了这么久的osx怎么没想到这招!!

直接看视频(非常大力的从youtube抓下来传youku了,请鼓掌)

CrazyText – My First MacRuby App

Crazy Text screenshot

前不久听说MacRuby 0.10 发布,并支持了Mac App Store 的发布.

于是边学习Ruby边学习MacRuby边学习cocoa 写了这么一个东西.

A MacOSX app written in Macruby to create some funny  effects for your texts.

提交时候提示MacRuby.framework内的几个link位置不对. 忘记什么提示了,需要手动修复几个link文件的地址.

对了1 :源码请移步 github-> https://github.com/xhan/CrazyText

对了2:

可以在appstore下载哦

部分UI仍然使用 objc编写(有些类和方法实在不知道如何用ruby实现)

个人感觉macruby 的学习曲线还真蛮高的,会cocoa,会ruby,还得会MacRuby,非常坑人,而且调试也非常又难度.

LessLyrics 歌词秀后续计划

最近发现了几款类似的竞争作品,看完后激动下.
又需要准备更新下Lesslyrics啦!

LessLyrics 是在去年7月份启动的,唯一的功能就是显示当前itunes正在播放中歌曲的歌词.
经过几个版本的功能和UI本质并未有太大改变,虽然计划了些比较酷的功能,却一直没实现(实力问题+时间问题+拖延症问题). 这次看了几个其他作者的作品,决定是该跨出新一步了.

由于对Mac软件开发不熟悉,做动画效果是最麻烦的,发个刚刚折腾出来的效果,虽然看起来没啥,但我还是很激动!! 咱们也有动画了.

新的歌词滑动效果(演示而已,别被这界面震惊了)

是的,你没看错.目前基本实现了千千静听的歌词显示效果!!!!!!!!!!!!!!!!!
激动吧!!!!!!!!!!!!!!!!!!!!
有木有!!!!!!!!!!!

更多新功能都会在0.8版本中出现, 这次, 可以期待!

 

======= 糗事百科的分割线  咯咯个个 ===============

CN视频啊,质量就忽略不计了,转型hll的失败了.
但这次视频上传过程倒蛮有趣味.

非常蛋疼的传了3个地方,youtube,vimeo 和国内的youku

首先是youku,它nnd不支持m4v格式,上传插件是flash,mac下中文支持的非常失败.而且需要填写所有质量后才能上传.
最无奈的是上传后提示转换中,但泥嘛的什么时候转换结束也没说明!!!

然后是youtube,直接用quicktime的share上传的,但是在上传后的publishing中卡了好久,于是放弃了.
尝试web端,支持拖拽(一下子就舒坦了),而且可以在上传过程中将内容资料补全(又舒坦了),而且上传后立刻就能观看视频!!(为什么转的如此迅速?? )

另外值得一提的是youku侧面的功能和youtube太像了,c2c,你懂得.

最后是我最喜爱的vimeo, UI做的灰常华丽,特别是进度条.其他方面上传时补填资料做的非常舒服,修改标题后直接能更新界面元素显示,非常直观. 当然vimeo没google这么厉害,人家也需要些时间转换视频格式. 但很贴心的给出了 转换时间的提示,好像还告诉您vip是不用排队的哟..

总结 上传视频体验 youtube > vimeo > youku (youku 完全没体验可言啊)

4月1日

标题和内容无关.两个视频

视频1: 你肯定会看第二遍!!

有没有!!

非常有创意的广告,收藏为本人top100广告之一.

视频2: group pressure

当然可能对当今的标新立异小朋友不是很适用.