10.10 Yosemite中如何将标题栏一起半透明化

似乎好久没发技术文章了(´・_・`),之前在折腾10.10的时候知道了NSVisualEffectView能将view毛玻璃化。但是光窗口内容半透明毛玻璃化了但是标题栏(title)却没有,显得略难看。
咱想做成这个样子:
スクリーンショット 2014-06-19 2.19.13
这样就会显得程序变得非常美观了。(虽然非激活状态整个界面都是白色好难看)

继续阅读“10.10 Yosemite中如何将标题栏一起半透明化”

已越狱的iOS上查看app是否已安装

想在MoeApps里显示该app是否已经安装。如果已安装则是直接显示“已安装”而不是程序的价格。
首先是看到了iHasApp这个库。实际测试发现这个只能看到app被他们收录而且是带有URL Scheme的才能够显示,也就是说并不能显示全部的app。不过这个倒是能通过审核上架。

但是咱的要求不是上架而是要显示完全部的app。
网上查了下,找到了这个
不过如果说知道BundleID(比如com.apple.mobilesafari)的话倒是能直接用,可惜MoeApps只知道纯数字的AppID,不过倒是可以通过先用AppID从iTuneslookupAPI获取到BundleID再进行判断是否已安装。

继续阅读“已越狱的iOS上查看app是否已安装”

Xcode上制作系统偏好设置面板项目(Preference Panes)

翻了半天网上没有很多关于这方面的,虽然Apple开发文档里写有。
嘛咱也不是说要翻译这个文档,而是简单介绍一下。
使用prefPane就和iOS的Settings里面的那些第三方程序设置一样,只不过Mac是直接安装到系统偏好设置面板里。而主要的功能就是作为外部设置来设置app,好处就是能变相绕过Sandbox来开启程序内部的一些不被允许的功能,当然同时app因为本身没开启这些功能可以通过Apple的审核上架到MacAppStore。

首先来了解下prefPane的原理,其实prefPane就是一个bundle,和app差不多,同样需要h和m文件,也有info.plist,也需要icon,而UI的话只有一个nib(当然可以做得多个然后之前切换什么的,那些就比较高级了)。而prefPane根据需要可以分成独立的prefPane来执行功能,也可以通过修改目标程序的设置plist文件达到设置app的功能,也可以直接使用NotificationCenter来通知程序:设置已经更改了!快做出反应!
这次主要介绍修改目标程序的偏好设置plist文件,优点是非常简单,缺点就是设置并不能马上生效,必须重新加载读取UserDefault或者重新运行程序。

继续阅读“Xcode上制作系统偏好设置面板项目(Preference Panes)”

萌电波可以说话了

虽然很早就想制作这个功能了,之前都在想有没有cooca现成的方法,发现都是只有针对文本的…没有后台的语音。
然后昨天突然想到…既然iOS和Mac程序都可以通过调用system()参数来执行命令行命令,然后命令行又能直接使用say这个调用系统语音….不就能让程序说话了么!∑(゚Д゚)咱果然是Genius!(拖走

初版只用十几分钟就完成了,能够读出各种操作以及歌曲名+演唱着名称。
不过之后花了不少时间(至少超过2小时)来优化…要知道原本可是同步操作,也就是系统在朗读的时候程序根本就无法操作,当遇到歌曲名或者演唱者名称特别长的…那会是非常痛苦的等待啊233
于是解决方法….这还是咱第一次使用NSTherd…简单说就是新开一个线程然后丢语音到另外一个线程去..
最后得到的效果…和iPod Shuffle内置的VoiceOver类似,不过感觉有点像是一般的音乐电台呢~

话说现在可以下载体验了:地址

默认这个功能是关闭的,需要在调教面板里打开:
屏幕快照 2013-06-26 14.38.50

当然光开启这个还是不行的,毕竟Mac系统默认的是英文/中文的嗓音,这样是没办法正常读日文的歌曲名的。需要手动去调整为日文的系统嗓音:
打开系统偏好设置面板,找到“听写与语音”,然后在“文本至语音”下有个“系统嗓音”,点开之后有个“自定…”可选:
屏幕快照 2013-06-26 16.03.41
之后找到日文的,勾上之后点“好”,后台会自动下载安装。装好之后就能正常读日文了:
屏幕快照 2013-06-26 16.03.54
咱现在用的是10.9 beta2,所以日文多个男声的Otoya可选,10.8以及以下的应该只有女声的Kyoko可选,个人觉得Otoya声音更大一些…Kyoko的声音太容易被淹没了(囧rz
朗读速率的话建议设置稍快一些…这样不至于等读完等太久…

话说咱玩这个玩上瘾了连歌曲都懒得听了光想听它读歌曲名称了_(:з」∠)_

整页面可变高度UIScrollView和可变高度UITableViewCell的方法

经常做程序会有需要一页显示不完的东西要滚动,而且又正好碰上比如里面的UITextView里文字字数不确定而如果字太多要做滚动的方式,虽然UITextView自带了UIScrollView但是还是觉得不如一整页滚动的效果好?
于是解决方法就是使用单独的UIScrollView,这货在程序中应该算是最不智能的东西吧?而且又正好碰上一些高度不确定的东西比如刚才说的UITextView里的文字,似乎不能不用代码来解决了。
但是作为非老开发者来说,非常不希望完全使用代码来写界面,那么应该如何配合StoryBoard或者nib文件来制作UIScrollView呢?
解决方法的思路是这样的,首先要根据文本来确定UITextView的高度,然后再加上界面上其他东西的高度(应该说是总高度),来绘制ScrollView。
可参考这个
于是第一步:确定UITextView的高度,而这需要根据文本来运算,既然文本长度不确定,自然要从文本上下功夫了:

NSString *text = self.textview.text;
CGSize stringSize = [text sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(320, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];

代码分解第一步获取到textview里的文本,然后根据文本来确定文本的大小(宽度和高度),其中需要根据你自己实际情况修改的:
1.boldSystemFontOfSize是textview里文本的字体大小。
2.CGSizeMake里的320这个要根据textview的宽度来修改,比如在这里宽度占完整个屏幕就是320(不是640哦,iOS后台会自动算Retina的)。
得到的stringSize就是实际文本的大小(包括宽度和高度,而下面我我们直接只用高度所以实际用的时候就直接:stringSize.height),接下来要把UITextView设置成这个尺寸,这样可以显示完全部的字:

[self.textview setFrame:CGRectMake(78, 0, 320, stringSize.height + 100)];

我为什么在后面会有个+ 100呢?因为实际调试的时候发现如果直接设置高度为stringSize.height会出现最下面两行被挡住了。总之这个数字可以根据自己实际情况进行调整。
而前面的78和0这两个对应的是textview所在界面的x,y值,这个可以直接在Storyboard或者nib里textview的size inspector里的View里看到,直接照用就行了。

高深人士应该能看得出其实这里已经是手动来绘制textview了,其实本来咱是想用setContentSize单独设定高度的,但是似乎没用…

设置完了UITextView之后来设置UIScrollView:

[self.scrollview setContentSize:CGSizeMake(320, stringSize.height + 200)];

这次后面+200是因为要包含界面上其他的东西。

于是这样应该就能达到效果了,如果有误差的话稍微调整以上提到的几个数值,应该能达到你想要的效果了。

另外还有一种解决方案就是使用静态的UITableView,因为其内置已经做好UIScrollView了,只要根据UITextView来决定cell的高度就可以了。
不过可变高度的cell又是如何做到的呢?上面已经知道了如何根据文本来确定高度,那么直接将高度应用在cell里不就好了~
于是:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger row = [indexPath row];
NSArray *array = arraylist[row];
NSString *text = [array valueForKey:@"message"];
CGSize stringSize = [text sizeWithFont:[UIFont boldSystemFontOfSize:12] constrainedToSize:CGSizeMake(292, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
return stringSize.height +50;
}

咱根据当前cell直接从array中直接读message,接下来的就和上面一样进行文本的长度确定,而到了最后则是返回stringSize.height,外加上自行调整的误差。

而至于当文本字体大小改变或者界面尺寸改变的时候,重新修改上面代码的对应变量即可(比如横屏等),重新运算过后就可以了。

最后附赠一个多点触控捏合缩小放大字体的代码(代码效果不是很好…参考):

- (void)viewDidLoad{
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinchGesture:)];
[self.textview addGestureRecognizer:pinchGesture];
}


- (IBAction)handlePinchGesture:(UIGestureRecognizer *)sender {
static int fontSize = 20;
if (sender.state == UIGestureRecognizerStateBegan)
{
// initialBounds = _view.bounds;
}
CGFloat factor = [(UIPinchGestureRecognizer *)sender scale];
if(factor > 1.0)
{
fontSize += 1;
}
else
{
fontSize -= 1;
}
if (fontSize >50) {
fontSize =50; return;
}
if (fontSize <5) { fontSize = 5; return; } [self.textview setFont:[UIFont fontWithName:@"Helvetica" size:fontSize]]; return; }

[Obj-c]匹配字段&NSArray里的Null问题&消除HTML转义字符

首先是监测字段匹配,假设要监测字符串string里是否含”a”这个字符:

if ([string rangeOfString:@"a"].location != NSNotFound) {
//do something
}

当NSArray为空或者里面某项为null的时候,在TableView或者其他什么界面经常会出现崩溃的问题。
解决方法:检测是否为空。但是普通的if (array != nil)是没用的,得这样操作:

if (array != [NSNull null]) {
//array not empty
}

尽管可能编译时会有警告…不过工作是正常的,至少程序不会再崩溃了。

最后,HTML输出的时候经常会连比如”&”或者空格之类的都转换成了“&amp;”或者“&nbsp;”这样的字符。
解决方法:手动转换回来。
加入以下代码:(为了防止被转换,咱已经将英文标点”;”更换成了全角的“;”,使用前请先手动更换回来)

-(NSString *)htmlEntityDecode:(NSString *)string{
string = [string stringByReplacingOccurrencesOfString:@"";" withString:@"\""];
string = [string stringByReplacingOccurrencesOfString:@"&apos;" withString:@"'"];
string = [string stringByReplacingOccurrencesOfString:@"&;" withString:@"&"];
string = [string stringByReplacingOccurrencesOfString:@"<;" withString:@"<"]; string = [string stringByReplacingOccurrencesOfString:@"&gt;" withString:@">"];
string = [string stringByReplacingOccurrencesOfString:@" ;" withString:@" "];
return string;
}

然后这么用:
string = [self htmlEntityDecode:string];
得到的string就是正常的了~