当前位置:  编程技术>移动开发
本页文章导读:
    ▪Nokia可以又着一次火了(修订版)        Nokia可以再着一次火了(修订版)本文作于前几天,由于今天的突发新闻,已作了修订。Nokia的着火史自从Elop那篇着火的平台备忘录出炉,Nokia的杯具就已经造成,唯一令人不解的就是:Elop为.........
    ▪ TextKit学习(4)通过boundingRectWithSize:options:attributes:context:计算文本尺寸        TextKit学习(四)通过boundingRectWithSize:options:attributes:context:计算文本尺寸之前用Text Kit写Reader的时候,在分页时要计算一段文本的尺寸大小,之前使用了NSString类的sizeWithFont:constrainedToSize:lineBrea.........
    ▪ 筹算自己做app,你们做过吗       打算自己做app,你们做过吗?最近手头上资金不足,想自己搞一下app赚点广告费,解决一下自己的零花钱问题,各位有没有做自己的app呢?打算用有米广告,各位觉得怎么样? 你们的收益是.........

[1]Nokia可以又着一次火了(修订版)
    来源: 互联网  发布时间: 2014-02-18
Nokia可以再着一次火了(修订版)

本文作于前几天,由于今天的突发新闻,已作了修订。

Nokia的着火史

自从Elop那篇着火的平台备忘录出炉,Nokia的杯具就已经造成,唯一令人不解的就是:Elop为什么还没有被开除?

距离这个备忘录事件已经过去两年半多,基于WinPhone平台的Lumia手机也出过好几款了,但是看看竞争对手们这两年半发生了些什么?不论是市场份额、机型(Android)、应用数量、还是平台的改进程度,都远远超过WinPhone——打这么长的名字的确挺麻烦,但我不愿意用缩写,因为通常我说到WP是指WordPress。

Elop当年说过不选择Android的理由是因为当时HTC和三星已经做大,Nokia后来加入这个红海难以脱颖而出,所以选择了全新的WinPhone,并且他相信微软做软件比Nokia更专业。

只可惜微软做软件的确更专业,但遗憾的是没有能够跟上移动世界的变化节奏。当年我吐槽《微软挪鸡鸭》的时候,还有很多微软粉来喷我,现在不知道他们都在哪里?

当然我也不是说Nokia马上就要死,但现在WinPhone的情况跟两年半前的Symbian相比,真没好多少。如果Nokia当初没有放弃Symbian,现在的情况也不会更糟到哪里去。既然当年可以着一次火,现在其实也是一个着火的好时候。

再着一次火

从Nokia决绝地放弃Symbian来看,估计是微软下的手,要求Nokia只做WinPhone,就现在的情况来看,跟我两年半前那篇预计的差不多,微软在这次的合作中得到了大部分好处,甚至自己卖起了Surface平板——幸好这货卖得不好(这货也被我吐槽过《Surface,送我都不要》),不然现在估计已经有Surface手机了。但是Nokia呢?给人剩下的印象就是:

拍照很NB

这跟Symbian时代给人的印象——抗摔——有什么分别?

我不知道它们之前的排它性协议时效多长,但我真的觉得Nokia应该准备后路,不应该再在WinPhone这一棵树上吊死。

那么它还有什么选择?

现在再选Android?当然不可能,那跟找死也没有什么分别了——还不如两年半前来呢。

WebOS?现在还有多少人记得它?虽然市场上二手Veer跟当年相比也没有跌价多少——折旧率远远低于Lumia 920之类——但毕竟是大势已去,现在状况基本等同于Symbian。

ChromeOS?现在有厂商在这用这货吗?Web真到了能代替本地应用的时候了?恐怕还需要假以时日吧。

还有什么?

Ubuntu Touch

去年我介绍过一个比较Geek的东西:Ubuntu for Android。我甚至还试了它的前身,那个Moto发明的WebTop,的确有一定的可用性,只是因为仍然太不成熟,可用性还是较差的。

但是现在情况不同了,Ubuntu已经在此基础上有了进一步的发展,那就是Ubuntu Touch,以及相应的硬件(计划明年发布):Ubuntu Edge。

8月初,我在G4PCC(我和几位Go4Pro.org的朋友一起搞的一年一度的小规模技术交流会)上看到了Mike那台刷了Ubuntu Touch的Nexus4,把玩了一把,感觉还是很不错的。

其实Ubuntu从桌面转向移动的准备工作已经做了很久。早在09年左右的时候,Ubuntu推出了NBR(NetBookRemix)版本,专门为小屏幕桌面设计了Unity UI。到了11年的时候,Unity已经成为Ubuntu的标配。

虽然早期的Unity的确不好用,但是经过这两年的发展,已经很不错了。而移动版的Ubuntu Touch也是采用了类似Unity的界面。

Ubuntu Touch既然叫Touch,当然是完全针对触摸屏设计的,大部分操作都信赖于按键,而是通过从边缘滑入的操作进行。包括那个Unity的侧边栏,都是通过边缘滑动显示的,还有正在运行的进程列表也是。

当然它最大的优点就是移动和桌面的一体化——插上键鼠外接显示器即成为全功能桌面版的Ubuntu。像WinPhone、WindowsRT、Window8那种精神分裂的东西完全是拍马也赶不上的(除非是新开发的兼容应用,大部分Windows应用根本不能运行在WindowsRT上,更不要说WinPhone了。

但是Ubuntu Touch不同,它可以运行所有Ubuntu桌面应用(当然不包括硬件相关的,比如需要特定硬件或使用X86指令集的),不存在这种分裂。另一方面,它也有一套自己的开发机制,基于QT和一种新的类似脚本的开发语言,而且以这种模式开发的应用本身就是兼容的,可以直接运行在未来版本的桌面Ubuntu上。

与其它的桌面移动一体方式相比,我觉得Ubuntu这条路是最有前途的。

Ubuntu Edge和Nokia

虽然我很看好Ubuntu Touch,但必须承认,移动的世界是依赖于硬件的,不同于桌面,有标准的PC硬件平台。所以Ubuntu搞了Edge计划,打算制造手机。

可惜的是,他们原本计划为Edge筹资的行动最后还是失败了……他们的目标是3200万美元,但最后只筹到1200万美元——虽然这已经是众筹的历史最高纪录了。

所以我觉得Nokia应该来和Ubuntu合作,比竟当年Nokia曾经拥有QT,从技术角度说,Nokia和Ubuntu Touch比和WinPhone应该有更亲近的关系。

当然,这一切的前提都是在于Nokia没有中木马的情况下……

更新消息

前几天微软宣布包耳膜将在一年内退休,结果微软的股价大涨7%。我戏称要是Nokia宣布Elop在一个月内退休,估计股价能涨70%……

某Nokia员工评论说:Nokia的股票现在都是地板价了,翻几番都有可能……

所以木马对于Nokia有多可恶,真是地球人都知道。

最新修订

今天的震撼性消息就是微软以71.7亿美元收购Nokia设备与服务部门(即手机部门,之后Nokia将仅剩网络和地图部门)。

估计木马的剧本大概是这样的:

三年前的一个晚上,包耳膜对木马说:我们要做手机,你帮我把NOKIA搞来,我让你接班。木马接令而去,几个月后丢出燃烧的平台备忘录,三年后终于大功告成,包耳膜宣布一年内退休,木马圆满回归,等待他的将是微软帝国的王位。

我早在两年半前就说过:

这事(指Nokia制造WinPhone)对于微软来说是一件好事,赚大发了,但对于NOKIA来说,无疑是北欧巨人倒下的第一步。

不幸言中。


    
[2] TextKit学习(4)通过boundingRectWithSize:options:attributes:context:计算文本尺寸
    来源: 互联网  发布时间: 2014-02-18
TextKit学习(四)通过boundingRectWithSize:options:attributes:context:计算文本尺寸

之前用Text Kit写Reader的时候,在分页时要计算一段文本的尺寸大小,之前使用了NSString类的sizeWithFont:constrainedToSize:lineBreakMode:方法,但是该方法已经被iOS7 Deprecated了,而iOS7新出了一个boudingRectWithSize:options:attributes:context方法来代替:



很碍眼的黄色警告标志。


先来看看iOS7 SDK包中关于boudingRectWithSize:options:attributes:context方法的定义:

// NOTE: All of the following methods will default to drawing on a baseline, limiting drawing to a single line.
// To correctly draw and size multi-line text, pass NSStringDrawingUsesLineFragmentOrigin in the options parameter.
@interface NSString (NSExtendedStringDrawing)
- (void)drawWithRect:(CGRect)rect options:(NSStringDrawingOptions)options attributes:(NSDictionary *)attributes context:(NSStringDrawingContext *)context NS_AVAILABLE_IOS(7_0);
- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary *)attributes context:(NSStringDrawingContext *)context NS_AVAILABLE_IOS(7_0);
@end

关于该方法,NSAttributedString其实也有一个同名的方法:

@interface NSAttributedString (NSExtendedStringDrawing)
- (void)drawWithRect:(CGRect)rect options:(NSStringDrawingOptions)options context:(NSStringDrawingContext *)context NS_AVAILABLE_IOS(6_0);
- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options context:(NSStringDrawingContext *)context NS_AVAILABLE_IOS(6_0);
@end
该方法在iOS6就可以使用了。


关于该类,有一篇关于NSAttributedString UIKit Additions Reference翻译的文章:http://blog.csdn.net/kmyhy/article/details/8895643

里面就说到了该方法:

boundingRectWithSize:options:context:

 返回文本绘制所占据的矩形空间。

- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options context:(NSStringDrawingContext *)context

参数

size

宽高限制,用于计算文本绘制时占据的矩形块。

The width and height constraints to apply when computing the string’s bounding rectangle.

options

文本绘制时的附加选项。可能取值请参考“NSStringDrawingOptions”。

context

context上下文。包括一些信息,例如如何调整字间距以及缩放。最终,该对象包含的信息将用于文本绘制。该参数可为 nil 。

返回值

一个矩形,大小等于文本绘制完将占据的宽和高。

讨论

可以使用该方法计算文本绘制所需的空间。size 参数是一个constraint ,用于在绘制文本时作为参考。但是,如果绘制完整个文本需要更大的空间,则返回的矩形大小可能比 size 更大。一般,绘制时会采用constraint 提供的宽度,但高度则会根据需要而定。

特殊情况

为了计算文本块的大小,该方法采用默认基线。

如果 NSStringDrawingUsesLineFragmentOrigin未指定,矩形的高度将被忽略,同时使用单线绘制。(由于一个 bug,在 iOS6 中,宽度会被忽略)

兼容性

  • iOS 6.0 以后支持。

声明于

NSStringDrawing.


另外,关于参数(NSStringDrawingOptions)options

typedef NS_ENUM(NSInteger, NSStringDrawingOptions) {
    NSStringDrawingTruncatesLastVisibleLine = 1 << 5, // Truncates and adds the ellipsis character to the last visible line if the text doesn't fit into the bounds specified. Ignored if NSStringDrawingUsesLineFragmentOrigin is not also set.
    NSStringDrawingUsesLineFragmentOrigin = 1 << 0, // The specified origin is the line fragment origin, not the base line origin
    NSStringDrawingUsesFontLeading = 1 << 1, // Uses the font leading for calculating line heights
    NSStringDrawingUsesDeviceMetrics = 1 << 3, // Uses image glyph bounds instead of typographic bounds
} NS_ENUM_AVAILABLE_IOS(6_0);

NSStringDrawingTruncatesLastVisibleLine:

如果文本内容超出指定的矩形限制,文本将被截去并在最后一个字符后加上省略号。如果没有指定NSStringDrawingUsesLineFragmentOrigin选项,则该选项被忽略。

NSStringDrawingUsesLineFragmentOrigin:

绘制文本时使用 line fragement origin 而不是 baseline origin。

The origin specified when drawing the string is the line fragment origin and not the baseline origin.

NSStringDrawingUsesFontLeading:

计算行高时使用行距。(译者注:字体大小+行间距=行距)

NSStringDrawingUsesDeviceMetrics:

计算布局时使用图元字形(而不是印刷字体)。

Use the image glyph bounds (instead of the typographic bounds) when computing layout.



简单写了一个Demo来看看该方法的使用,并比较了一下各个options的不同,首先是代码:

    NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:textView.text];
    textView.attributedText = attrStr;
    NSRange range = NSMakeRange(0, attrStr.length);
    NSDictionary *dic = [attrStr attributesAtIndex:0 effectiveRange:&range];   // 获取该段attributedString的属性字典
    // 计算文本的大小
    CGSize textSize = [textView.text boundingRectWithSize:textView.bounds.size // 用于计算文本绘制时占据的矩形块
                                                  options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading // 文本绘制时的附加选项
                                               attributes:dic        // 文字的属性
                                                  context:nil].size; // context上下文。包括一些信息,例如如何调整字间距以及缩放。该对象包含的信息将用于文本绘制。该参数可为nil
    NSLog(@"w = %f", textSize.width);
    NSLog(@"h = %f", textSize.height);
再看看不同的options下控制台的输出结果:

     NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
     2013-09-02 21:04:47.470 BoudingRect_i7_Demo[3532:a0b] w = 322.171875
     2013-09-02 21:04:47.471 BoudingRect_i7_Demo[3532:a0b] h = 138.000015
    
     NSStringDrawingUsesLineFragmentOrigin // The specified origin is the line fragment origin, not the base line origin
     2013-09-02 17:35:40.547 BoudingRect_i7_Demo[1871:a0b] w = 318.398438
     2013-09-02 17:35:40.549 BoudingRect_i7_Demo[1871:a0b] h = 69.000000
    
     NSStringDrawingTruncatesLastVisibleLine // Truncates and adds the ellipsis character to the last visible line if the text doesn't fit into the bounds specified. Ignored if NSStringDrawingUsesLineFragmentOrigin is not also set.
     2013-09-02 17:37:38.398 BoudingRect_i7_Demo[1902:a0b] w = 1523.408203
     2013-09-02 17:37:38.400 BoudingRect_i7_Demo[1902:a0b] h = 13.800000
    
     NSStringDrawingUsesFontLeading // Uses the font leading for calculating line heights
     2013-09-02 17:40:45.903 BoudingRect_i7_Demo[1932:a0b] w = 1523.408203
     2013-09-02 17:40:45.905 BoudingRect_i7_Demo[1932:a0b] h = 13.800000
    
     NSStringDrawingUsesDeviceMetrics // Uses image glyph bounds instead of typographic bounds
     2013-09-02 17:42:03.283 BoudingRect_i7_Demo[1956:a0b] w = 1523.408203
     2013-09-02 17:42:03.284 BoudingRect_i7_Demo[1956:a0b] h = 13.800000

其中如果options参数为NSStringDrawingUsesLineFragmentOrigin,那么整个文本将以每行组成的矩形为单位计算整个文本的尺寸。(在这里有点奇怪,因为字体高度大概是13.8,textView中大概有10行文字,此时用该选项计算出来的只有5行,即高度为69,而同时使用NSStringDrawingUsesFontLeading | NSStringDrawingUsesLineFragmentOrigin却可以得出文字刚好有10行,即高度为138,这里要等iOS7官方的文档出来再看看选项的说明,因为毕竟以上文档是iOS6的东西)

如果为NSStringDrawingTruncatesLastVisibleLine或者NSStringDrawingUsesDeviceMetric,那么计算文本尺寸时将以每个字或字形为单位来计算。

如果为NSStringDrawingUsesFontLeading则以字体间的行距(leading,行距:从一行文字的底部到另一行文字底部的间距。)来计算。

各个参数是可以组合使用的,如NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine。


根据该方法我调整了一下Reader的分页方法:(主要是将被iOS7 Deprecated的sizeWithFont:constrainedToSize:lineBreakMode:方法改成了boudingRectWithSize:options:attributes:context:方法来计算文本尺寸)

/* 判断是否需要分页和进行分页动作 */
-(BOOL)paging
{
    /* 获取Settings中设定好的字体(主要是获取字体大小) */
    static const CGFloat textScaleFactor = 1.; // 设置文字比例
    NSString *textStyle = [curPageView.textView tkd_textStyle]; // 设置文字样式
    preferredFont_ = [UIFont tkd_preferredFontWithTextStyle:textStyle scale:textScaleFactor]; //设置prferredFont(包括样式和大小)
    NSLog(@"paging: %@", preferredFont_.fontDescriptor.fontAttributes); // 在控制台中输出字体的属性字典
    
    
    /* 设定每页的页面尺寸 */
    NSUInteger height = (int)self.view.bounds.size.height - 40.0; // 页面的高度
    
    
    /* 获取文本的总尺寸 */
    NSDictionary *dic = preferredFont_.fontDescriptor.fontAttributes;
    CGSize totalTextSize = [bookItem.content.string boundingRectWithSize:curPageView.textView.bounds.size
                                                                 options:NSStringDrawingUsesLineFragmentOrigin
                                                              attributes:dic
                                                                 context:nil].size;
    NSLog(@"w = %f", totalTextSize.width);
    NSLog(@"h = %f", totalTextSize.height);
    
    
    /* 开始分页 */
    if (totalTextSize.height < height) {
        /* 如果一页就能显示完,直接显示所有文本 */
        totalPages_   = 1;             // 设定总页数为1
        charsPerPage_ = [bookItem.content length]; // 设定每页的字符数
        textLength_   = [bookItem.content length]; // 设定文本总长度
        return NO;                     // 不用分页
    }
    else {
        /* 计算理想状态下的页面数量和每页所显示的字符数量,用来作为参考值用 */
        textLength_                       = [bookItem.content length];                   // 文本的总长度
        NSUInteger referTotalPages        = (int)totalTextSize.height / (int)height + 1; // 理想状态下的总页数
        NSUInteger referCharactersPerPage = textLength_ / referTotalPages;               // 理想状态下每页的字符数
        // 输出理想状态下的参数信息
        NSLog(@"textLength             = %d", textLength_);
        NSLog(@"referTotalPages        = %d", referTotalPages);
        NSLog(@"referCharactersPerPage = %d", referCharactersPerPage);
        
        
        /* 根据referCharactersPerPage和text view的高度开始动态调整每页的字符数 */
        // 如果referCharactersPerPage过大,则直接调整至下限值,减少调整的时间
        if (referCharactersPerPage > 1000) {
            referCharactersPerPage = 1000;
        }
        
        // 获取理想状态下的每页文本的范围和pageText及其尺寸
        NSRange range       = NSMakeRange(referCharactersPerPage, referCharactersPerPage); // 一般第一页字符数较少,所以取第二页的文本范围作为调整的参考标准
        NSString *pageText  = [bookItem.content.string substringWithRange:range]; // 获取该范围内的文本
        NSLog(@"%@", pageText);
        
        
        NSRange ptrange = NSMakeRange(0, pageText.length);
        NSDictionary *ptdic = [[bookItem.content attributedSubstringFromRange:ptrange] attributesAtIndex:0 effectiveRange:&ptrange];
        CGSize pageTextSize = [pageText boundingRectWithSize:curPageView.textView.bounds.size
                                                     options:NSStringDrawingUsesLineFragmentOrigin
                                                  attributes:ptdic
                                                     context:nil].size;
        
        // 若pageText超出text view的显示范围,则调整referCharactersPerPage
        NSLog(@"height = %d", height);
        while (pageTextSize.height > height) { 
            NSLog(@"pageTextSize.height = %f", pageTextSize.height);
            referCharactersPerPage -= 2;                                      // 每页字符数减2
            range                   = NSMakeRange(0, referCharactersPerPage); // 重置每页字符的范围
            ptdic = [[bookItem.content attributedSubstringFromRange:range] attributesAtIndex:0 effectiveRange:&range];
            CGSize pageTextSize = [pageText boundingRectWithSize:curPageView.textView.bounds.size
                                                         options:NSStringDrawingUsesLineFragmentOrigin
                                                      attributes:ptdic
                                                         context:nil].size;
            pageText                = [bookItem.content.string substringWithRange:range];        // 重置pageText
            
            pageTextSize = [pageText boundingRectWithSize:curPageView.textView.bounds.size
                                                  options:NSStringDrawingUsesLineFragmentOrigin
                                               attributes:ptdic
                                                  context:nil].size; // 获取pageText的尺寸
        }
        
        // 根据调整后的referCharactersPerPage设定好charsPerPage_
        charsPerPage_ = referCharactersPerPage; 
        NSLog(@"cpp: %d", charsPerPage_);
        
        // 计算totalPages_
        totalPages_ = (int)bookItem.content.length / charsPerPage_ + 1;
        NSLog(@"ttp: %d", totalPages_);
        
        // 计算最后一页的字符数,防止范围溢出
        charsOfLastPage_ = textLength_ - (totalPages_ - 1) * charsPerPage_;
        NSLog(@"colp: %d", charsOfLastPage_);
        
        // 分页完成
        return YES;
    }
}
这样就看不到碍眼的黄色警告标志了。



重要的是,由于该方法计算文本的尺寸更为准确,所以可以使得分页后页与页之间的连贯性好了很多,而且每页的空间利用率都提高了很多,每页的文字几乎铺满了整个页面。




 




    
[3] 筹算自己做app,你们做过吗
    来源: 互联网  发布时间: 2014-02-18
打算自己做app,你们做过吗?

最近手头上资金不足,想自己搞一下app赚点广告费,解决一下自己的零花钱问题,各位有没有做自己的app呢?打算用有米广告,各位觉得怎么样?

你们的收益是如何呢?能在这里晒晒吗?


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3