2012年7月27日 星期五

Mac 的特殊符號輸入法

轉貼 http://www.cppblog.com/biao/archive/2009/11/06/100257.html

另外詳細圖表在 http://pigmu.com/1321


glyphs_mac_chars.png


glyphs_mac_more.png






glyphs_mac_more2.png

2012年7月25日 星期三

class method中的變數呼叫

在實做CalculatorBrain時
遇到要在class method使用全域或外在變數

我遇到的情形與網址中所遇到的相同
http://stackoverflow.com/questions/9998461/dont-know-how-to-access-property-from-class-method-in-xcode


正確作法
external double store_value

@interface CalculatorBrain : NSObject
 
另一種錯誤方法 
@property double ssvalue; 
 
- (void)pushOperand:(double)operand; // - = instance method
- (double)performOperation: (NSString *)operation;
@property (nonatomic,readonly) id program;
+ (double)runProgram:(id)program; // + = class method
+ (NSString *)descriptionOfProgram:(id)program;
@end

...(.m)
 
@interface CalculatorBrain()
@property (nonatomic,strong) NSMutableArray *programStack;
@property (nonatomic) double storedValue;
@end
@implementation CalculatorBrain
@synthesize programStack = _programStack;
@synthesize storedValue = _storedValue;
 
 
- (double) ssvalue 
{
   return ssvalue; 
} 
 
- (void) setSsvalue:(double) ssvalue 
{
   self.ssvalue = ssvalue;
}
 
+ (double) popOperandOffStack:(NSMutableArray *)stack{
    double result = 0;

    id topOfStack = [stack lastObject];
    if (topOfStack) 
        [stack removeLastObject];

    if ([topOfStack isKindOfClass:[NSNumber class]])
    {
        result = [topOfStack doubleValue];
    } 
    else if ([topOfStack isKindOfClass:[NSString class]]) 
    {
        NSString *operation = topOfStack;
        if ([operation isEqualToString:@"+"]){
            result = [self popOperandOffStack:stack] + [self popOperandOffStack:stack];
        } else if ([operation isEqualToString:@"-"]){
            result = -[self popOperandOffStack:stack] + [self popOperandOffStack:stack];
        } else if ([operation isEqualToString:@"*"]){
            result = [self popOperandOffStack:stack] * [self popOperandOffStack:stack];
        } else if ([operation isEqualToString:@"/"]){
            double divide = [self popOperandOffStack:stack];
            if(divide){
                result = [self popOperandOffStack:stack] / divide;
            } else {
                result = 0;
            }
        } else if ([operation isEqualToString:@"1/x"]){
            result = 1 / [self popOperandOffStack:stack];
        } else if ([operation isEqualToString:@"sqrt"]){
            double sqrtNumber = [self popOperandOffStack:stack];
            if (sqrtNumber > 0){
                result = sqrt(sqrtNumber);
            } else {
                result = 0;
            }
        } else if ([operation isEqualToString:@"sin"]){
            result = sin( [self popOperandOffStack:stack]);
        } else if ([operation isEqualToString:@"cos"]){
            result = cos( [self popOperandOffStack:stack]);
        } else if ([operation  isEqualToString:@"MS"]){
            self.storedValue = [self popOperandOffStack:stack];
        } else if ([operation isEqualToString:@"MR"]){
            result = self.storedValue; //error here
        } else if ([operation isEqualToString:@"MC"]){
            result = [self popOperandOffStack:stack];
            self.storedValue = 0; //error here
        } else if ([operation isEqualToString:@"M+"]){
            result = [self popOperandOffStack:stack];
            //self.storedValue = self.storedValue + result; //error here
           storevalue = storevalue +result;
           setSsvalue(ssvalue + result);      
        } else if ([operation isEqualToString:@"M-"]){
            result = [self popOperandOffStack:stack];
            //self.storedValue = self.storedValue - result; //error here
          storevalue = storevalue -result; 
           setSsvalue(ssvalue - result); 
         } else if ([operation isEqualToString:@"C"]){
            result = 0;
            while ( [self popOperandOffStack:stack] )
            {
                //clear operands until returns NO
            }
        } else if ([operation isEqualToString:@"CE"]){
            result = 0;
            //self.storedValue = 0; //error here
           storevalue = 0;
           //setSsvalue(0); 
            while ( [self popOperandOffStack:stack] )
            {
                //clear operands until returns NO
            }
        }   

        if (![operation isEqualToString:@"MS"] && ![operation isEqualToString:@"CE"])
        {
            return result;
        } else {
            return self.storedValue;
        }
    }
    return result;
}

2012年7月22日 星期日

segue

此處細節可參考:http://www.raywenderlich.com/zh-hans/18162/ios-5-storyboard-%E5%85%A5%E9%97%A8-2

Apple參考資料區:https://developer.apple.com/library/ios/#recipes/xcode_help-interface_builder/articles/EstablishingBindingsDragging.html#//apple_ref/doc/uid/TP40009971-CH21-SW1

 segue(发音为:seg-way)),它表示了从一个界面切换到另一个界面。
是storyboard的一項功能。




 以上三個圖是從史丹福的課程內容上剪下的。


Segue的幾種模式

參考http://www.cnblogs.com/ghj1976/archive/2012/05/30/2526559.html

在storyboard中,segue有几种不同的类型,在iphone和ipad的开发中,segue的类型是不同的。
在iphone中,segue有:push,modal,和custom三种不同的类型,这些类型的区别在与新页面出现的方式。
而在ipad中,有push,modal,popover,replace和custom五种不同的类型。

modal 模态转换

最常用的场景,新的场景完全盖住了旧的那个。用户无法再与上一个场景交互,除非他们先关闭这个场景。
是在viewController中的标准切换的方式,包括淡出什么的,可以选切换动画。
Modalview:就是会弹出一个view,你只能在该view上操作,而不能切换到其他view,除非你关闭了modalview.
Modal View对应的segue type就是modal segue。
*Modal:Transition to another scene for the purposes of completing a task.当user在弹出的modalview里操作完后,就应该dismiss the modal view scene然后切换回the originalview.

push


Push类型一般是需要头一个界面是个Navigation Controller的。
是在navigation View Controller中下一级时使用的那种从右侧划入的方式
*Push:Create a chain of scenes where the user can move forward or back.该segue type是和navigation viewcontrollers一起使用。

popover(iPad only)

popover 类型,就是采用浮动窗的形式把新页面展示出来
*Popover(iPad only):Displays the scene in a pop-up “window” over top of the current view.

*Replace (iPad only):

替换当前scene,
Replace the current scene with another. This is used in some specialized iPad viewcontrollers (e.g. split-view controller).

custom


就是自定义跳转方式啦。
*Custom:Used for programming a customtransition between scenes.
在Storyboard中使用自定义的segue类型

xcode4.2的一些新東西

轉貼自
http://wsqwsq000.iteye.com/blog/1402150



1. 工程项目模板类型的更改
          Xcode4时代                                           Xcode4.2新模板
Navigation-based Application  ------->Master-Detail Application => iphone
Splite View-based Application ------->Master-Detail Application => ipad
OpenGL ES Application --------------->OpenGL Game
Tab Bar Application      --------------->Tabbed Application
Utility Application         --------------->Utility Application
View-based Application --------------->Single View Application
Window-based Application------------>Empty Application
 
2.  新增一编译级特性——Automatic Reference Counting
 这似乎是Xcode4.2也增加了类似其他面向对象语言的GC(垃圾回收器)的概念。不知道我的理解是否正确?但在实践中若是iphone应用编程或导入以前的工程项目最好还是禁用ARC,(我们自己勤快点养成释放清理对象的习惯。)方法为:Project Info -> Apple LLVM compiler 3.0 - Language -> Objective-C Automatic Referencing Counting, 设置为NO即可

否则会对release,retainCount,retain等内存相关操作在编译时出现红色警告:

 

 3. 新增特性——Storyboard
Storyboard是Xcode4.2新增的又一个特性,它将原有工程中的所有xib文件集成在一起,用拖曳的方式建立ViewController相关之间的跳转关系,使得整个程序的UI跳转逻辑清楚明了。简单地说,storyboard引入了2个概念:
scene:一个场景,由一个viewController和相关的xib表示。
segue:(英文原意为继续、持续)。在这是用于连接scenes,其有多种类型,包括:Push,Modal,Popover and more。
当然segue也负责传递数据和返回数据。
整个程序的界面转换就是在各个scene之间切换。界面跳转关系,比如按哪个键跳到哪个界面,是由segue来描述。segue也可以带数据,以便做数据传递。(也因此被说是抄袭Adobe的Flash)。
要点:必须有一个viewController是作为storyboard的初始界面的,及需要勾选上Initial Scene项。如下图:


StoryBoard相对于以前的NIB/XIB的优势:
  • 能够减少很多与View相关的代码量。
  • 能够使View和Controller进一步解耦。
  • 能够优化程序的“页面流”,使程序的结构更清楚。
      通常,NIB是和ViewController相关联的,很多时候ViewController都有其对应的NIB文件。该文件的作用就是描述用户界面以 及初始化对象和界面元素对象。虽然这些都可以在代码中来实现,但为了高效编写程序代码,xCode给我们提供了IB来绘制界面。而StoryBoard的 引入,则是进一步加强了这方面的功能,之前的NIB文件没有办法描述ViewController之间的跳转过渡,只能通过代码中调用类似 -presentModalViewController:animated:或-pushViewController:animated:这个两个方 法来实现。现在,在StoryBoard中引入了Segue这一概念,由Segue定义从一个ViewController到另一个 ViewController的过渡。只需要像之前连接界面对象和Action Method那样将ViewController之间用合适的Segue连接起来即可,无需任何手写代码。即使是自定义Segue,也只需编写Segue 的实现,而无需编写调用的代码,一切都由StoryBoard帮我们调用。

 要准确用好StoryBoard机制,必须严格遵守MVC原则。要让View和Controller充分解耦;并且不同的Controller之 间也是充分解耦。所以AppDelegate就应该是处理UIApplication的回调,而不应该负责用户界面的处理。更不应该直接把 AppDelegate当ViewController用,乃至直接在UIWindow上绘制界面。虽然,这有可能简单明了,毕竟UIWindow也是 UIView的子类。但我们还是要有优良的习惯:由ViewController来负责处理View才是正确之道。从近期苹果针对xCode的项目模板的 变化上看也反映这种优化趋势:
      在Xcode 4时,程序项目模板(如View-Based Application)开始鼓励使用UIWindow的rootViewController属性来指定第一屏的ViewController,以保证 AppDelegate只专注于它应该做的事情。如今Xcode4.2引入StoryBoard后,AppDelegate就直接不管 ViewController的事情了,第一屏使用的ViewController(即rootViewController)可以在 StoryBoard中设置。
如何从NIB/XIB迁移到StoryBoard,有些什么改变?
  • ViewController不需要NIB/XIB文件,连接Outlet和Action的操作都可以在StoryBoard上完成。
  • 孤 立View(独立于ViewController的View)是不能出现在StoryBoard里,所有View必须通过ViewController来 管理。(这样,StoryBoard更像是Controller对象的容器,而不是View对象的容器,以前NIB/XIB倒显得可以视为View对象的 容器)
  • ViewController之间的过渡代码不需要了,用StoryBoard的Segue直接可视化连接不同的ViewController。
  • UIWindow对象的作用被进一步淡化,在StoryBoard图上没有体现出AppDelegate对象——因为它本来就不应该来处理界面View的。
  • 代码编写要严格遵守MVC设计模式,才能用好StoryBoard来高效开发程序。
实践中的问题:
      XCode项目如果包含StoryBoard创建的,就无法在iOS 4.x的模拟器和iOS 4.x的真机上调试,运行,不报错,但是得到的结果只有黑屏。这应该是storyboard只有iOS5支持的原因吧。
 
4. UIGestureRecognizer使用更方便,居然可视化。
      在UIGestureRecognizers之前的时代,如果想要检测一个手势,如滑过(swipe),你不得不在UIView视图内对每个touch动 作注册通知,如touchesBegan,touchesMoves,touchesEnded。程序员要编写相近的代码来检测各个touches动作, 导致微妙的错误和应用程序之间的不一致。
      在iOS3.0,Apple开始引入新的UIGestureRecognizer类来补救。这些类提供检测诸如 taps,pinches,rotations,swipes,pans和long presses等手势的默认实现,通过使用它们,再也不需要编写繁重的代码量,也能使程序正常运行。
使用UIGestureRecognizers非常简单,只有两步:
1. Create a gesture recognizer。需要指定一个回调方法使手势识别器当手势starts,changes,或ends时,能发送这些更新。
2. Add the gesture recognizer to a view。每个gesture recognizer都是唯一关联一个视图。当视图内部发生一个触摸(touch)时,手势识别器将寻找相匹配类型的触摸,找到匹配的就通知回调函 数。 [self.view addGestureRecognizer:recognizer];
你可以编码方式执行这两步。不过现在StoryBoard Editor中可视化添加一个手势识别器非常容易。居然可以从Objects Library中拖放进来。

UIGestureRecognizer的衍生类別有以下几种:
  • UITapGestureRecognizer     点一下
  • UIPinchGestureRecognizer   二指往内或往外拨动
  • UIRotationGestureRecognizer  旋转
  • UISwipeGestureRecognizer     滑动,快速移动
  • UIPanGestureRecognizer       拖移,慢速移动
  • UILongPressGestureRecognizer  长按
這些手势別在使用上也很简单,只要在使用前定义并添加到对应的视图上即可(在StoryBoard可直接拖放到对应的视图上)。