当前位置:  编程技术>移动开发
本页文章导读:
    ▪非项目型项目经理辩论胶片        非项目型项目经理答辩胶片 非项目型项目经理答辩胶片 ......
    ▪ UIViewController器皿机理分析        UIViewController容器机理分析   一. UIViewController 做iOS开发的经常会和UIViewController打交道,从类名可知UIViewController属于MVC模型中的C(Controller),说的更具体点它是一个视图控制器,管理着一个视图(view.........
    ▪ 在EditText/TextView中插入表情图片、样式、上划线等       在EditText/TextView中插入表情图片、样式、下划线等 EditText:  通常用于显示文字,但有时候也需要在文字中夹杂一些图片,比如QQ中就可以使用表情图片,又比如需要的文字高亮显示等等,如何.........

[1]非项目型项目经理辩论胶片
    来源: 互联网  发布时间: 2014-02-18
非项目型项目经理答辩胶片
非项目型项目经理答辩胶片

    
[2] UIViewController器皿机理分析
    来源: 互联网  发布时间: 2014-02-18
UIViewController容器机理分析

 

一. UIViewController

做iOS开发的经常会和UIViewController打交道,从类名可知UIViewController属于MVC模型中的C(Controller),说的更具体点它是一个视图控制器,管理着一个视图(view)。

UIViewController的view是lazy loading的,当你访问其view属性的时候,view会从xib文件载入或者通过代码创建(覆盖loadView方法,自定义其view hierarchy),并返回,如果要判断一个View Controller的view是否已经被加载需要通过其提供的isViewLoaded方法来判断。 
view加载后viewDidLoad会被调用,这里可以进行一些数据的请求或加载,用来更新你的界面。 
当view将被加入view hierarchy中的时候viewWillAppear会被调用,view完成加入的时候viewDidAppear会被调用,同样当view将要从view hierarchy中移除的时候viewWillDisappear会被调用,完成移除的时候viewDidDisappear会被调用。 
当内存紧张的时候,所有的UIViewController对象的didReceiveMemoryWarning会被调用,其默认实现是 如果当前viewController的view的superview是nil的话,则将view释放且viewDidUnload会被调用,viewDidUnload中你可以进行后继的内存清理工作(主要是界面元素的释放,当再次加载的时候需要重建)。

如果想要展示一个View Controller,一般有如下一种途径

  • 设置成Window的rootViewController(iOS 4.0之前UIWindow并没有rootViewController属性,只能通过addSubview的方式添加一个View Controller的view)
  • 使用某个已经存在的Container来展示,比如使用UINavigationController来展示某个View Controller [navigationController pushViewController:vc animated:YES];
  • 以模态界面的方式展现出来 presentModalViewController
  • 以addSubview的方式将使其view作为另一个View Controller的view的subView
  • 直接使用4种方法是比较危险的,上一级 View Controller并不能对当前View Controller的 生命周期相关的函数进行调用,以及旋转事件的传递等。



    二.Hierarchy

    我们知道一个View可以将另一个View添加为子View(subview),构成一个View Hierarchy.当某一个View添加到window的View Hierarchy中时,将被“显示”。每一个View Controller管理着的其实就是一个View Hierarchy.而View Controller本身可以有Child View Controller,所以也存在一个 View Controller Hierarchy的概念,当View Controller收到上层传来的诸如旋转,显示事件的时候,需要传递给它的Child View Controller. 一般情况下,View Hierarchy 和 View Controller Hierarchy需要保持一致性,比如一个View Controller的view的superView是由其parent view controller管理着



    三.Container

    一个iOS的app很少只由一个ViewController组成,除非这个app极其简单。 当有多个View Controller的时候,我们就需要对这些View Controller进行管理。 那些负责一个或者多个View Controller的展示并对其视图生命周期进行管理的对象,称之为容器,大部分容器本身也是一个View Controller,这样的容器可以称之为Container View Controller,也有极少数容器不是View Controller,比如UIPopoverController,其继承于NSObject。

    我们常用的容器有 UINavigationController,UITabbarController等,一般容器有一些共同的特征:

  • 提供对Child View Controller进行管理的接口,比如添加Child View Controller,切换Child View Controller的显示,移除Child View Controller 等
  • 容器“拥有”所有的Child View Controller
  • 容器需要负责 Child View Controller的appearance callback的调用(viewWillAppear,viewDidAppear,viewWillDisaapper,viewDidDisappear),以及旋转事件的传递
  • 保证view hierarchy 和 view controller hierarchy 层级关系一致,通过parent view controller将child view controller和容器进行关联
  • 从上面可以看出来,实现一个Container View Controller并不是一个简单的事情,好在iPhone的界面大小有限,一般情况下一个View Controller的view都是充满界面或者系统自带容器的,我们无需自己创建额外的容器,但是在iPad中情况就不同了。



    四. Custom Container View Controller

    在iOS 5之前框架并不支持自定义 Container View Controller, iOS 5开始开放了一些新的接口来支持支持自定义容器

    addChildViewController:
    removeFromParentViewController
    transitionFromViewController:toViewController:duration:options:animations:completion:
    willMoveToParentViewController:
    didMoveToParentViewController:
    

    其中前两个接口比较重要,可以直接改变View Controller 的 Hierarchy。

    有点意外的是,在不做任何额外设置的情况下进行如下操作

    [viewController.view addSubview:otherViewController.view]
    

    iOS 5中otherViewController是可以立刻收到viewWillAppear和viewDidAppear的调用。

    至于旋转事件的传递以及其他时机viewWillAppear viewDidAppear的调用是需要建立在 [viewController addChildViewController:otherViewController]基础上的。

    当我们需要在iOS 4上实现自定义容器,或者有时候我们不想让viewWillAppear这类方法被自动调用,而是想自己来控制,这个时候我们就得需要手动来调用这些方法,而不是由框架去自动调用。 iOS 5中可以很方便的禁用掉自动调用的特性,覆盖automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers返回NO

    但是单单覆盖这个方法在iOS5下还是有问题的,当执行下面的语句的时候

    [viewController.view addSubview:otherViewController.view]
    

    otherViewController还是是可以立刻收到viewWillAppear和viewDidAppear的调用。 
    解决这一问题的方法就是在iOS5的时候调用[viewController.view addSubview:otherViewController.view]之前 进行如下操作

    [viewController addChildViewController:otherViewController]
    

    总的来说实现兼容iOS 4和iOS 5的容器有不少问题和注意点的

  • view加入view层级前后分别调用viewWillAppear和viewDidAppear;容器的viewWillAppear,viewDidAppear,viewWillDisappear,viewDidDisappear中需要对当前显示的Child View Controller调用相同的方法,容器需要保证Child View Controller的viewWillAppear调用之前Child View Controller的view已经load了.还有一点就是保证容器的View不会出现bounds为CGRectZero的情况,因为如果此View包含多个subview,其bounds改变的时候subview会根据自己的autoresizingMask改变frame,但是当bounds变为0再变为非0的时候,subview的frame就有可能不是你想要的了(比如某个subview的autoresizingMask为UIViewAutoresizingFlexibleBottomMargin)
  • 容器的shouldAutorotateToInterfaceOrientation中需要检测每一个Child View Controller的shouldAutorotateToInterfaceOrientation如果一个不支持,则看做不支持
  • 容器的willRotateToInterfaceOrientation,didRotateFromInterfaceOrientation,willAnimateRotationToInterfaceOrientation方法中需要将这些事件传递给所有的Child View Controller
  • 由于UIViewController的parentViewController属性为只读,且iOS4中没有提供容器支持的接口(iOS 5中容器支持的接口会间接的维护这个属性),所以为了使得childViewController和容器得以关联,我们可以顶一个View Controller的基类,添加一个比如叫做superController的属性用来指定对应的parentViewController
  • 由于UIViewController的interfaceOrientation为只读属性,且iOS5中没有提供容器接口,所以UIViewController的这个interfaceOrientation变的不可信,为了取得当前UIViewController的orientation我们可以用UIWindow下的rootViewController的interfaceOrientation的值
  • 容器的viewDidUnload方法中需要对view未释放的childViewController的view进行释放,且调用其viewDidUnload方法
  • 苹果对UIViewController以及其使用有着非常详细的文档 UIViewController Reference , ViewController Programming Guide。

    ------------------------------------------

     

     

    对于iPhone app,UIViewController类提供了基本的视图管理模式。当设备改变方向的时候view controller的视图会自动随之旋转的。如果视图和子视图的autoresizing属性设置是对的,这时候视图又没有随着设备一起旋转,可能是以下的原因:

    1.view controller没有完成代理方法

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation;

    也要实现了shouldAutorotateToInterfaceOrientation方法,同时shouldAutorotateToInterfaceOrientation方法要返回YES来支持所有的旋转方向

     

    2.view controller的UIView属性嵌入在UIWindow中,并非是一个附加的view controller

    你可能会发现shouldAutorotateToInterfaceOrientation方法只会在view controller启动的时候被调用,不会因为设置的旋转而在被调用。这是因为view controller束缚着他们所管理的视图,view controller是用来处理时间的响应链的一部分。view controller是从UIResponder继承而来,同时他被插入到他所管理的视图和他的superview之间。因此,通常的做法是在你的app中有一个主view controller来作为响应链的一部分。通常来说会添加一个主view controller,例如UINavigationController, UITabBarController或者UIViewController到UIWindow上。

    例如

    [myWindow addSubview:primaryViewController.view]; 

    如果你添加了另外一个view controller的UIView属性到UIWindow(anotherController和主view controller在同一个等级上)

    [myWindow addSubview:anotherController.view];

    anotherController将不会接受旋转事件,只有第一个view controller(primaryViewController)会接受旋转事件。

     

    3.你添加了view controller的UIView属性到UIWindow作为subview,但是过早的release它。

    UIWindow会retain视图,而不是view controller。你不能过早的release他。在UIApplicationDelegate子类中定义他为retain属性。

     

    4.在UITabBarController或者UINavigationController中的子view controller没有对同一方向的支持。

    为了确保所有的子view controller旋转正确,你的每一个view controller,每一个tab或者额navigation都要完成shouldAutorotateToInterfaceOrientation,而且必须支持对于同一方向的旋转,也就是说对于同一方向的位置要返回为YES。

     

    5.重写-(id)init:或者 -(id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle 方法的时候没有调用super。

    对于对象的初始化,在你的view controller的init或者initWithNibName方法中必须要调用super。


        
    [3] 在EditText/TextView中插入表情图片、样式、上划线等
        来源: 互联网  发布时间: 2014-02-18
    在EditText/TextView中插入表情图片、样式、下划线等

    EditText:
      通常用于显示文字,但有时候也需要在文字中夹杂一些图片,比如QQ中就可以使用表情图片,又比如需要的文字高亮显示等等,如何在android中也做到这样呢?
    记得android中有个android.text包,这里提供了对文本的强大的处理功能。
    添加图片主要用SpannableString和ImageSpan类:
         Drawable drawable = getResources().getDrawable(id); 
            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); 
            //需要处理的文本,[smile]是需要被替代的文本 
            SpannableString spannable = new SpannableString(getText().toString()+"[smile]"); 
            //要让图片替代指定的文字就要用ImageSpan 
            ImageSpan span = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE); 
            //开始替换,注意第2和第3个参数表示从哪里开始替换到哪里替换结束(start和end) 
           //最后一个参数类似数学中的集合,[5,12)表示从5到12,包括5但不包括12 
            spannable.setSpan(span, getText().length(),getText().length()+"[smile]".length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);   
            setText(spannable); 
    将需要的文字高亮显示:
    public void highlight(int start,int end){ 
            SpannableStringBuilder spannable=new SpannableStringBuilder(getText().toString());//用于可变字符串 
            ForegroundColorSpan span=new ForegroundColorSpan(Color.RED); 
            spannable.setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
            setText(spannable); 
        } 
    加下划线:
    public void underline(int start,int end){ 
            SpannableStringBuilder spannable=new SpannableStringBuilder(getText().toString()); 
            CharacterStyle span=new UnderlineSpan(); 
            spannable.setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
            setText(spannable); 
        } 
    组合运用:
    SpannableStringBuilder spannable=new SpannableStringBuilder(getText().toString()); 
            CharacterStyle span_1=new StyleSpan(android.graphics.Typeface.ITALIC); 
            CharacterStyle span_2=new ForegroundColorSpan(Color.RED); 
            spannable.setSpan(span_1, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
            spannable.setSpan(span_2, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
            setText(spannable); 
    案例:带有\n换行符的字符串都可以用此方法显示2种颜色
        /**
         * 带有\n换行符的字符串都可以用此方法显示2种颜色
         * @param text
         * @param color1
         * @param color2
         * @return
         */ 
        public SpannableStringBuilder highlight(String text,int color1,int color2,int fontSize){ 
            SpannableStringBuilder spannable=new SpannableStringBuilder(text);//用于可变字符串 
            CharacterStyle span_0=null,span_1=null,span_2; 
            int end=text.indexOf("\n"); 
            if(end==-1){//如果没有换行符就使用第一种颜色显示 
                span_0=new ForegroundColorSpan(color1); 
                spannable.setSpan(span_0, 0, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
            }else{ 
                span_0=new ForegroundColorSpan(color1); 
                span_1=new ForegroundColorSpan(color2); 
                spannable.setSpan(span_0, 0, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
                spannable.setSpan(span_1, end+1, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
                span_2=new AbsoluteSizeSpan(fontSize);//字体大小 
                spannable.setSpan(span_2, end+1, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
            } 
            return spannable; 
        } 
    以上实际都是Html.fromHtml(html)的代码实现形式。
    =============================================================================
    TextView: (方法与EditView类似)
    如何让一个TextView中的关键字高亮显示?
       /**
         * 关键字高亮显示
         * @param target 需要高亮的关键字
         */ 
        public void highlight(String target){ 
            String temp=getText().toString(); 
            SpannableStringBuilder spannable = new SpannableStringBuilder(temp); 
            CharacterStyle span=null; 
            Pattern p = Pattern.compile(target); 
            Matcher m = p.matcher(temp); 
            while (m.find()) { 
                span = new ForegroundColorSpan(Color.RED);//需要重复! 
                spannable.setSpan(span, m.start(), m.end(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
            } 
            setText(spannable); 
        }


        
    最新技术文章:
    ▪Android开发之登录验证实例教程
    ▪Android开发之注册登录方法示例
    ▪Android获取手机SIM卡运营商信息的方法
    ▪Android实现将已发送的短信写入短信数据库的...
    ▪Android发送短信功能代码
    ▪Android实现退出时关闭所有Activity的方法 iis7站长之家
    ▪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