zoukankan      html  css  js  c++  java
  • [BS] 小知识点总结-03

    1.Autolayout中“constrain to margins”

      Autolayout中的页面边距的问题ios8以后的UIView增加了layoutMargins属性,在Storyboard/IB中使用AutoLayout布局时,一般都取消勾选“constrain to margins”,如果勾选,即使你在约束里设置某个控件的上下左右均为0,当查看其真实坐标时,发现x=16,y=20,而且控件的右侧离self.view的最右边也有16point的间距,下边没有间隙。故一般取消勾选即可。

    2. 

    2.1 modal出来的控制器使用下面2个方法都能将其关闭,这两种写法有什么区别啊?
    [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
    [self dismissViewControllerAnimated:YES completion:nil];

    2.2

        window.rootViewController = tabBarController; //window特有方法,rootVC将与window同生同死

      【tabBarController addChildViewController:navController】; //@property(nonatomic,copy) NSArray *viewControllers;

      navController= [UINavigationController alloc] initWithRootViewController:viewController]; //rootVC被加入导航栈最底部,即navController.viewControllers的第一个元素,与navC同生同死。相当于Sb中Embed in NavigationController。

    注意:

    (1) 以上关系中,viewController的view会被自动添加到以window为基础的UI层级中(注意self.view并没有被直接加到window上,二者之间还有6/7个视图层级)。

    (2) navC和tabC都有切换页面的功能,都有viewControllers属性,又有childViewControllers属性(二者的值完全相同,后者readonly)。而普通的viewController都只有childViewControllers属性,没有viewControllers属性。

    (3) tabBar上面超过5个按钮,那么系统会自动将第5个按钮变为“更多”,第5个及以后的按钮就被放进“more”中。The "More" navigation controller will not be returned by -viewControllers, but it may be returned by -selectedViewController.

    3. UIView.subviews

    所有的UIView都有一个subviews数组属性,管理着它的所有子视图,可以通过以下方法在某个位置插入子视图

      UIView *view = [[UIView alloc]initWithFrame:self.view.frame];

        view.backgroundColor = [UIColor greenColor];

        [self.view insertSubview:view atIndex:0];

    4. 自定义UI控件init方法

    //从Xib创建会调用如下两个方法
    //最先调用
    - (instancetype)initWithCoder:(NSCoder *)aDecoder {
        if (self = [super initWithCoder:aDecoder]) {  
        }
        return self;
    }
    //接着调用
    - (void)awakeFromNib {
    
    }
    //最后调用
    - (void)drawRect:(CGRect)rect {
        [super drawRect:rect];
    }
    
    
    
    //完全代码创建
    //先调用
    - (instancetype)initWithFrame:(CGRect)frame {
        if (self = [super initWithFrame:frame]) {
        }
        return self;
    }
    //然后调用
    - (void)drawRect:(CGRect)rect {
        [super drawRect:rect];
    }

    5.设置UI控件圆角方法

      5.1代码设置(需要获取该控件的引用)

      self.loginButton.layer.cornerRadius = 5;

          self.loginButton.layer.masksToBounds = YES;  //bounds默认是不可见的,只有盖住它才可见。

      5.2在Xib中利用KVC直接设值

      

    6.  

      不管UITextField加载self.view哪个子视图里,在任何一个方法中调用[self.view endEditing]; 都可以把界面上弹出的所有的键盘收回去。

      通过修改某UI控件的约束来实现动画,在修改完约束后,在[UIView animateWithDuration:1.0 animations:^{ [self.view layoutIfNeeded]; }];中不一定非要用该UI控件的父视图来调用layoutIfNeeded方法,最简单的通用方法是直接让self.view重新布局。

    7. 设置背景色的3种方法

        titlesView.backgroundColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.5]; //通用

        titlesView.backgroundColor = [[UIColor whiteColor]colorWithAlphaComponent:0.5];  //设置常见颜色及Alpha

        titlesView.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.5]; //特殊用法:设置RGB相同的灰色及Alpha

    /*

        + (UIColor *)blackColor;      // 0.0 white 

        + (UIColor *)darkGrayColor;   // 0.333 white

        + (UIColor *)lightGrayColor;  // 0.667 white

        + (UIColor *)whiteColor;      // 1.0 white

        + (UIColor *)grayColor;       // 0.5 white

        + (UIColor *)clearColor;      // 0.0 white, 0.0 alpha

    */

    8. 计算文本框宽高的2种方法 

      NSDictionary *textDict = @{ NSFontAttributeName:[UIFont systemFontOfSize:12] };  

    //方法1:

        CGFloat maxW = self.contentView.frame.size.width - 2* margin;  //限定最大的宽度为:cell宽度-2*margin 

      CGRect textRect = [textStr boundingRectWithSize:CGSizeMake(maxW, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:textDict context:nil];  //如果不限制宽高,就写(MAXFLOAT, MAXFLOAT)

    //方法2:    

      //计算文本框宽高,不设置最大宽度限制,所有文字显示在一横行上(等价于上一种方法不限制宽高)

      CGSize textSize = [text sizeWithAttributes:attrDict];

    9. 根据文字调整宽高sizeToFit:

    [label sizeToFit];      [button sizeToFit];//调整里面的图片框和Label    [button.titleLabel sizeToFit];

    注意:调用sizeToFit会让控件的size立马有值,产生和[self.view layoutIfNeed]类似的效果。

    10.

    取消scrollView和tableView自动布局向下偏移64,要用当前控制器的属性self.automaticallyAdjustsScrollViewInsets = NO;

    注意:该属性是视图控制器的属性,并不是scrollView和tableView的属性。因误以为是scrollView和tableView的属性,在敲代码时Xcode死活没提示。郁闷了一阵,下次不在此栽跟头了。

    //以下写法报错(UIView并没有该属性)

    scrollView.automaticallyAdjustsScrollViewInsets NO; //直接编译报错

    tableView.automaticallyAdjustsScrollViewInsets = NO; //直接编译报错

    //以下属性用于关闭UIView的Autoresizing,一般是在使用AutoLayout给该UIView添加约束前使用。注意别和视图控制器的automaticallyAdjustsScrollViewInsets属性混淆了。

    tableView.translatesAutoresizingMaskIntoConstraints = NO; 

    scrollView.translatesAutoresizingMaskIntoConstraints = NO;

    11.

    //scrollView子控件的frame是参考contentSize左上角(0,0)点来设定的,与scrollView坐标没有关系。

     12. 关于scrollView的一些方法:

     a.通过设置offSet让scrollView匀速滚动:[scrollView setContentOffset:offset animated:YES];

       b.监听setContentOffset停止滚动的时刻:

          //该方法专门监控setContentOffset: animated:方法后的滚动

      - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {  }

     c. 监听用户拖动后,停止滚动的时刻:

      //Decelerating的方法特指:用户拖拽过后的减速(用户不施力是匀速滚动)

      - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { }

     

    13.  scrollView.pagingEnabled = YES; //启用分页(拖动时要么滚动一整页,要么不滚动,跟contentOffset有关)

    14. 注意UI控件的viewWithTag:方法(如[self.view viewWithTag:0]),会返回view的视图层级中与给定tag匹配的view,也包含view自身在内。所有的UI控件不设置tag值,默认是0。

    Return:  The view in the receiver’s hierarchy whose tag property matches the value in the tag parameter.

    14.

    tableVC会自动调整tableView顶部内边距为64(状态栏20+导航栏44),即使设置tableViewController.automaticallyAdjustsScrollViewInsets = NO;仍然会被设置向下偏移20(状态栏宽度)。如果想让tableView顶格,需手动设置frame的y = 0;

    //打印继承自scrollView的相关偏移属性
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
      NSLog(@"tableView.frame:%@",NSStringFromCGRect(tableView.frame));
     NSLog(@"tableView.contentInsets:%@",NSStringFromUIEdgeInsets(tableView.contentInset));//tableVC会自动调整tableView顶部内边距为64
      NSLog(@"tableView.contentOffset:%@",NSStringFromCGPoint(tableView.contentOffset));
      NSLog(@"tableView.contentSize:%@",NSStringFromCGSize(tableView.contentSize));
    }
    
    2016-05-17 18:54:34.622 904. 待办清单ToDoList[45231:2587500] *** -[NSKeyedUnarchiver initForReadingWithData:]: data is NULL
    2016-05-17 18:55:03.588 904. 待办清单ToDoList[45231:2587500] tableView.frame:{{0, 0}, {320, 480}}
    2016-05-17 18:55:03.588 904. 待办清单ToDoList[45231:2587500] tableView.contentInsets:{64, 0, 0, 0}
    2016-05-17 18:55:03.588 904. 待办清单ToDoList[45231:2587500] tableView.contentOffset:{0, -64}
    2016-05-17 18:55:03.588 904. 待办清单ToDoList[45231:2587500] tableView.contentSize:{320, 88}

     15. 设置了tableView的内边距,同时也需要设置滚动条的内边距,否则不协调。

        //设置tableView内边距(此代码必须放到addSubview之前,一显示页面才会生效)

        tableView.contentInset = UIEdgeInsetsMake(CGRectGetMaxY(self.titlesView.frame), 0, self.tabBarController.tabBar.height, 0);

        //设置滚动条的内边距

        tableView.scrollIndicatorInsets = tableView.contentInset;

    16.

      //如果导航栏是半透明的,mj_header在停止刷新后虽然自动隐藏了,但是会被看到。这是只需要设置mj_header允许自动改变透明度即可

        self.tableView.mj_header.automaticallyChangeAlpha = YES;

    17. 使用MJRefreshAutoNormalFooter时的问题

      使用如下代码添加footer刷新:self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreTopics)];  在数据尚未返回,或者加载失败footer都会跑到最顶部。

    解决方法1: 第一次进来或者每次reloadData否会调一次numberOfRowsInSection:在此方法中控制footer是否隐藏  self.tableView.mj_header.hidden = (self.topics.count == 0);

    解决方法2:直接使用[MJRefreshBackFooter footerWithRefreshingBlock:^(void)refreshingBlock];比较省事,数据为出现或加载失败,footer都会自动隐藏在最下方看不见的地方。

     

    18.

    SVProgressHUD 只需要在第一次尝试的时候采用默认黑色Mask的样式,以后就不需要设置了。

    //提示用户加载失败

    [SVProgressHUD setDefaultMaskType:SVProgressHUDMaskTypeBlack];

     19.

    因UIViewController有这样一个分类,所以对于所有的视图控制器只要是最底层是tabBarController,不管中间隔着多少个控制器,都可以拿到该属性。vc.tabBarController和vc.navigationController属性类似。

    @interface UIViewController (UITabBarControllerItem)

    @property(null_resettable, nonatomic, strong) UITabBarItem *tabBarItem; // Automatically created lazily with the view controller's title if it's not set explicitly.

    @property(nullable, nonatomic, readonly, strong) UITabBarController *tabBarController; // If the view controller has a tab bar controller as its ancestor, return it. Returns nil otherwise.

    @end

     20. 设置ios素材图片的拉伸模式

    21.

     在布局时如果发现某个控件frame尺寸设置正确,但显示出来却不是想要的尺寸frame,一般很可能是因为autoresizing自动伸缩属性(只能设置自身和superView的关系)的影响。解决方法: iconImageView.autoresizingMask = UIViewAutoresizingNone;

    22. UIImageView两种创建方法:

    //1.常规方法: 

    UIImageView *imgView = [[UIImageView alloc]init];  imgView.image = [UIImage imageNamed:@"angle"];

    //2.创建和image同等尺寸的imageView

    UIImageView *imgView1 = [[UIImageView alloc]initWithImage:@"angle"];

    23.

    Xib中加载起来的视图控制器的self.view尺寸是(600,600),此时如果想拿到真实的屏幕尺寸,只能通过[UIScreen mainScreen].bounds来获取屏幕尺寸的准确值。

    //WZShowViewController.h/.m/.xib测试结果如下:

    - (void)viewDidLoad {  

        [super viewDidLoad];

        NSLog(@"self.view:%@",self.view);

    }  //打印结果:self.view:<UIView: 0x7fb72d2ab860; frame = (0 0; 600 600);

     

    24.将UIImage保存到相册:

     UIImageWriteToSavedPhotosAlbum(self.imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);

    //苹果推荐使用image:didFinishSavingWithError:contextInfo:

    - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{

        if (error) {

            [SVProgressHUD showErrorWithStatus:@"保存失败"];

        } else {

            [SVProgressHUD showSuccessWithStatus:@"保存成功"];

        }

    }

    25. 九宫格的写法

        NSArray *images = @[@"video",@"picture",@"text",@"audio",@"publish-review",@"offline"];
        NSArray *titles = @[@"视频",@"图片",@"文字",@"声音",@"审核",@"离线"];
        
        CGFloat buttonW = 72;
        CGFloat buttonH = buttonW + 30;
        CGFloat leadingMargin = 15; //第一个按钮距屏幕左边沿举例
        NSInteger colomns = 3; //每行3个按钮
        NSInteger rows = (images.count % colomns == 0) ? (images.count / colomns) : (images.count/colomns + 1); //计算有多少行
        CGFloat maginX = (screenW - 2 * leadingMargin - colomns * buttonW) / (colomns - 1); //x方向间距
        CGFloat maginY = 15; //y方向间距
        CGFloat row1Y = (screenH - buttonH * rows - maginY * (rows - 1)) * 0.5; //垂直居中
        
        for (int i = 0; i < images.count; i++) {
            
            WZVerticalButton *button = [[WZVerticalButton alloc]init];
            [button setImage:[UIImage imageNamed:images[i]] forState:UIControlStateNormal];
            [button setTitle:titles[i] forState:UIControlStateNormal];
            [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            
            button.x = leadingMargin + (i % colomns) * (buttonW + maginX);
            button.y = row1Y + (i / colomns) * (buttonH + maginY);
            button.width = buttonW;
            button.height = buttonH;
    
            [self.view addSubview:button];
        
        }

     26.

    将CGPoint类型包装成对象[NSValue valueWithCGPoint:CGPointMake(100, 100)];

     27. 新建window并显示

    UIWindow *window = [[UIWindow alloc]init];

    window.hidden = NO;

    Note1:想让新建的window显示出来,只需要设置hidden = NO;即可。窗口是老大,别人添加到它上面,它自己想显示,直接取消隐藏即可。

    Note2: [window makeKeyAndVisible]; 等价于 [window makeKeyWindow]; window.hidden = NO;

    Note3: 每个窗口的触摸事件是独立的,不会向后穿透。    

    Note4: 同级别的window,最后设置hidden=NO;的窗口显示在最上面。窗口有3种级别:Normal < StatusBar < Alert 级别。将一个window的windowLevel设置为statusBar级别,然后设置和状态栏一样的frame,相当于自定义状态栏。

    28.

    (1). 设置view的边框和阴影

       

    (2).

    view.layer.masksToBounds = YES;  官方解释:A Boolean indicating whether sublayers are clipped to the layer’s bounds. 设置YES, 则view内部的子layer都会被view.layer.bound所裁剪。  实现阴影效果时,必须设为NO,否则阴影效果消失。设置ImageLayer并显示边框时,必须将masksToBounds设为NO,否则子layer会露出来。

    (3).  

    只要设置layer.cornerRadius=10; 和 layer.borderWidth=3; 就可以显示圆角,和layer.masksToBounds无关,该属性仅影响子layer是否被裁剪。  

    29. 

    (1) 利用transform属性可以对UIView控件进行平移Translation、缩放scale、旋转rotation

    struct CGAffineTransform {

      CGFloat a, b, c, d;

      CGFloat tx, ty;

    };

    创建一个CGAffineTransform类型的transform属性

    view.transform = CGAffineTransformMakeTranslation(CGFloat tx,  CGFloat ty) ;
    view.transform = CGAffineTransformMakeScale(CGFloat sx, CGFloat sy);
    view.transform = CGAffineTransformMakeRotation(CGFloat angle)  //注意:angle是弧度制,并不是角度制

    在某个transform的基础上进行叠加

    CGAffineTransform CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty);
    CGAffineTransform CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy);
    CGAffineTransform CGAffineTransformRotate(CGAffineTransform t, CGFloat angle);
     
    清空之前设置的transform属性    view.transform = CGAffineTransformIdentity;

    CG_EXTERN const CGAffineTransform CGAffineTransformIdentity  /* The identity transform: [ 1 0 0 1 0 0 ]. */

    (2) 可以给UIView.layer添加transform.transition、transform.scale、transform.rotation核心动画

     CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.scale"];

        anim.toValue = @0.5;

        anim.repeatCount = MAXFLOAT;

        [self.view.layer addAnimation:anim forKey:nil];

    30. 让layoutSubViews方法中某段代码只执行一次

    //1.使用内部全局BOOL变量记录代码是否被执行过

    static BOOL excuted = NO; //定义内部全局变量

    - (void)layoutSubviews{

      if (excuted == NO) {

      NSLog(@"该代码只会被执行一次!");

      }

      excuted = YES; //全局变量和程序同生同死,只要程序没有重启,下次执行layoutSubviews方法,excuted = YES;中间的代码不会被执行

    }

    //2.使用dispatch_once

      static dispatch_once_t  onceToken;    dispatch_once(&onceToken, ^{  });

     

     

     

     

     

     

     

    iOS开发者交流群:180080550
  • 相关阅读:
    Working with macro signatures
    Reset and Clear Recent Items and Frequent Places in Windows 10
    git分支演示
    The current .NET SDK does not support targeting .NET Core 2.1. Either target .NET Core 2.0 or lower, or use a version of the .NET SDK that supports .NET Core 2.1.
    Build website project by roslyn through devenv.com
    Configure environment variables for different tools in jenkins
    NUnit Console Command Line
    Code Coverage and Unit Test in SonarQube
    头脑王者 物理化学生物
    头脑王者 常识,饮食
  • 原文地址:https://www.cnblogs.com/stevenwuzheng/p/5443751.html
Copyright © 2011-2022 走看看