美文网首页不明觉厉iOSiOS开发技术iOS
实时显示iOS编写UI代码效果

实时显示iOS编写UI代码效果

作者: Sam_Lau | 来源:发表于2015-04-23 15:53 被阅读53745次

编写iOS应用UI的方式大概有两种,一种是Storyboard/Xib,另一种是手写代码。采用Storyboard/Xib方式组织UI,由于提供可视化的特性,只要从UI库中拖动UI控件,便可以显示结果,极大地提高开发速度。但面临一个问题就是多人协作开发,由于所有的UI都放在同一个Storyboard文件中,使用Git/SVN合并代码就会出现冲突。多人协作开发还不是主要问题,有人提出可以创建多个Storyboard来分开UI编写,而Storyboard/Xib最主要问题是代码复用性比较差。所以有些人就选择手写UI代码,这样不仅可以解决多人协作开发问题,而且通过自定义控件在多个View使用。但每次手写UI代码后都要编译、构建和运行,最后在模拟器显示,这样会拖慢开发速度。如果每次修改UI控件后,保存修改便实时在模拟器显示修改后结果,就可以极大的提高编写UI的速度。


Live Change.gif

Auto Layout

Auto Layout是什么

Auto Layout是一个基于constraint(约束)的布局系统,它根据UI元素之间约束关系来调整UI元素的位置和大小。

Auto Layout解决什么问题

  • 更容易适配不同分辨率设备的屏幕(iPhone 6 Plus, iPhone 6, iPhone 5s/5, iPhone 4s/4)
  • 当设备旋转时不需要做额外处理
  • 使用constraint来描述布局逻辑,更利于理解和清晰

如何使用Auto Layout

Auto Layout中约束的类对应是NSLayoutConstraint, 而创建NSLayoutConstraint对象主要有两种方式,第一种是

+ (id)constraintWithItem:(id)view1
               attribute:(NSLayoutAttribute)attribute1
               relatedBy:(NSLayoutRelation)relation
                  toItem:(id)view2
               attribute:(NSLayoutAttribute)attribute2
              multiplier:(CGFloat)multiplier
                constant:(CGFloat)constant;

上面方法主要意思是,某个view1的attribute1等于(小于或等于/大于或等于)某个view2的attribute2的multiplier倍加上constant。而attribute主要由表示位置(上/下/左/右)和大小(宽/高)的以下几个值:

typedef enum: NSInteger {
   NSLayoutAttributeLeft = 1,
   NSLayoutAttributeRight,
   NSLayoutAttributeTop,
   NSLayoutAttributeBottom,
   NSLayoutAttributeLeading,
   NSLayoutAttributeTrailing,
   NSLayoutAttributeWidth,
   NSLayoutAttributeHeight,
   NSLayoutAttributeCenterX,
   NSLayoutAttributeCenterY,
   NSLayoutAttributeBaseline,
   NSLayoutAttributeNotAnAttribute = 0
} NSLayoutAttribute;

简化一下,使用公式可以表达为:

view1.attribute1 = view2.attribute2 * multiplier + constant

第二种方式是:

+ (NSArray *)constraintsWithVisualFormat:(NSString *)format 
                                 options:(NSLayoutFormatOptions)opts 
                                 metrics:(NSDictionary *)metrics 
                                   views:(NSDictionary *)views;

这种方式主要是采用Visual Format Language(可视化格式语言)来描述约束布局,虽然语法比较简洁,但是可读性比较差和容易出错。

Auto Layout存在问题

虽然Auto Layout在布局view方面是非常强大和灵活,但是创建constraint的语法过于繁杂,引用Masonry一个例子:

UIView *superview = self;

UIView *view1 = [[UIView alloc] init];
view1.translatesAutoresizingMaskIntoConstraints = NO;
view1.backgroundColor = [UIColor greenColor];
[superview addSubview:view1];

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);

[superview addConstraints:@[

    //view1 constraints
    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeTop
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeTop
                                multiplier:1.0
                                  constant:padding.top],

    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeLeft
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeLeft
                                multiplier:1.0
                                  constant:padding.left],

    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeBottom
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeBottom
                                multiplier:1.0
                                  constant:-padding.bottom],

    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeRight
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeRight
                                multiplier:1
                                  constant:-padding.right],

 ]];

如此简单的一个例子都要编写这么多行代码,想象一下如果创建多个view的constraint时会多么痛苦啊。另一个方式是采用Visual Format Language (VFL),虽然语法比较简洁,但是可读性比较差和容易出错。

Masonry

为什么使用Masonry

Masonry是采用链式DSL(Domain-specific language)来封装NSLayoutConstraint,通过这种方式编写Auto Layout布局代码更加易读和简洁。
使用Masonry的MASConstraintMaker来表达相同constraint

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);

[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.equalTo(superview.mas_top).with.offset(padding.top); //with is an optional semantic filler
    make.left.equalTo(superview.mas_left).with.offset(padding.left);
    make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom);
    make.right.equalTo(superview.mas_right).with.offset(-padding.right);
}];

甚至可以更短

[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.edges.equalTo(superview).with.insets(padding);
}];

如何使用

使用Masonry创建constraint来定义布局的方式有三种:mas_makeConstraintsmas_updateConstraintsmas_remakeConstraints

1. mas_makeConstraints

使用mas_makeConstraints创建constraint后,你可以使用局部变量或属性来保存以便下次引用它;如果创建多个constraints,你可以采用数组来保存它们。

// in public/private interface
@property (nonatomic, strong) MASConstraint *topConstraint;

...

// when making constraints
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
    self.topConstraint = make.top.equalTo(superview.mas_top).with.offset(padding.top);
    make.left.equalTo(superview.mas_left).with.offset(padding.left);
}];

...
// then later you can call
[self.topConstraint uninstall];
2. mas_updateConstraints

有时你需要更新constraint(例如,动画和调试)而不是创建固定constraint,可以使用mas_updateConstraints方法

// this is Apple's recommended place for adding/updating constraints
// this method can get called multiple times in response to setNeedsUpdateConstraints
// which can be called by UIKit internally or in your code if you need to trigger an update to your constraints
- (void)updateConstraints {
    [self.growingButton mas_updateConstraints:^(MASConstraintMaker *make) {
        make.center.equalTo(self);
        make.width.equalTo(@(self.buttonSize.width)).priorityLow();
        make.height.equalTo(@(self.buttonSize.height)).priorityLow();
        make.width.lessThanOrEqualTo(self);
        make.height.lessThanOrEqualTo(self);
    }];

    //according to apple super should be called at end of method
    [super updateConstraints];
}
3. mas_remakeConstraints

mas_remakeConstraintsmas_updateConstraints比较相似,都是更新constraint。不过,mas_remakeConstraints是删除之前constraint,然后再添加新的constraint(适用于移动动画);而mas_updateConstraints只是更新constraint的值。

- (void)changeButtonPosition {
    [self.button mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.size.equalTo(self.buttonSize);

        if (topLeft) {
            make.top.and.left.offset(10);
        } else {
            make.bottom.and.right.offset(-10);
        }
    }];
}

想了解以上三个代码片段的更多细节,可以下载Masonry iOS Examples工程查阅。

Classy

Classy简介和特性

Classy是一个能与UIKit无缝结合stylesheet(样式)系统。它借鉴CSS的思想,但引入新的语法和命名规则。

灵活内嵌的语法

{ } : ; 这些语法符号是可选的,你可以选择适合自己的风格来表达stylesheet。

你可以使用{ } : ; 来限定stylesheet

$main-color = #e1e1e1;

MYCustomView {
 background-color: $main-color;
 title-insets: 5, 10, 5, 10;
 > UIProgressView.tinted {
   progress-tint-color: black;
   track-tint-color: yellow;
 }
}

^UIButton.warning, UIView.warning ^UIButton {
 title-color[state:highlighted]: #e3e3e3;
}

或者你使用空格来限定stylesheet

$main-color = #e1e1e1

MYCustomView 
  background-color $main-color
  title-insets 5, 10, 5, 10
  > UIProgressView.tinted 
    progress-tint-color black
    track-tint-color yellow

^UIButton.warning, UIView.warning ^UIButton 
  title-color[state:highlighted] #e3e3e3

默认样式

Classy在应用程序Bundle默认查找文件名为stylesheet.cas的样式文件。如果你采用这个文件名,你可以不用做任何东西就能加载样式文件。
但如果你想指定其他file path(样式文件名),你可以创建[CASStyler defaultStyler]

[CASStyler defaultStyler].filePath = [[NSBundle mainBundle] pathForResource:@"myStyles.cas" ofType:nil];

如果你还想当发生错误时,获取错误信息以便于调试,可以使用-(void)setFilePath:error:

NSError *error = nil;
NSString filePath = [[NSBundle mainBundle] pathForResource:@"myStyles.cas" ofType:nil];
[[CASStyler defaultStyler] setFilePath:filePath error:&error];

如果你是使用Storyboard/Xib组织UI界面,那就需要在main.mint main(int argc, char * argv[])方法设置** filePath,这样可以确保在创建UIWindow之前加载stylesheet。否则(采用手写UI代码),你在 AppDelegate.m- (BOOL)application:didFinishLaunchingWithOptions:方法设置filePath**

Live Reload

Live Reload是实时显示编写UI代码效果的关键特性,它能够实时检查stylesheet文件变化,无需重新编译、构建和运行模拟器,从而极大提高开发速度。
为了启用Live Reload,你需要指定stylesheet路径,并且只运行在模拟器上。

#if TARGET_IPHONE_SIMULATOR
    NSString *absoluteFilePath = CASAbsoluteFilePath(@"../Styles/stylesheet.cas");
    [CASStyler defaultStyler].watchFilePath = absoluteFilePath;
#endif

Selectors

Style Selectors是指定哪个view使用哪种样式的方式。主要有三种方法来指定目标view:

  1. Object Class
  2. View Hierarchy
  3. Style Class

你可以混合使用三种方法,例子如下:

/* match views
 * where class is UIButton or UIButton subclass
 * and styleClass is "large"
 * and superview class is UITabBar
 */
 
UITabBar > ^UIButton.large { }

想了解具体如何使用,请查阅官网Selectors章节

为了避免与Objective-C的message selectors混淆,术语style selectors表示Classy stylesheets的selectors

Properties

Classy支持所有UIAppearance的属性和方法,也支持与UIAppearance无关的很多属性。Classy使用与UIKit相同属性命名,所以你不必考虑如何将style property映射到Objective-C的property
UIPageControl类的属性如下:

@property (nonatomic,retain) UIColor *pageIndicatorTintColor;
@property (nonatomic,retain) UIColor *currentPageIndicatorTintColor;

style property的名字采用与objective-c一样的名字

UIPageControl {
  pageIndicatorTintColor black
  currentPageIndicatorTintColor purple
}

style property的命名规则采用kebab case

UIPageControl {
  page-indicator-tint-color black
  current-page-indicator-tint-color purple
}

想了解具体如何使用,请查阅官网Properties章节

Keep it DRY(Don't Repeat Yourself)

在编程中一个很重要的原则就是避免重复,这不仅可以大量减少重复代码,并且使得代码更加容易复用和维护。Classy提供三种方式避免代码重复:grouping, nestingvariables

Grouping

如果有两个以上的style selectors共用相同的属性时

UISlider.info {
  minimum-track-tint-color black
  maximum-track-tint-color purple
}

UISlider.error {
  minimum-track-tint-color black
  maximum-track-tint-color purple
  thumb-tint-color red
}

我们可以提取相同的属性到分组style selector中

UISlider.info, UISlider.error {
  minimum-track-tint-color black
  maximum-track-tint-color purple
}

UISlider.error {
  thumb-tint-color red
}
Nesting

如果两个以上style selectors共用相同的view hierarchy时

UICollectionView {
  background-color #a2a2a2
}

UICollectionView > UICollectionViewCell {
  clips-to-bounds NO
}

UICollectionView > UICollectionViewCell UILabel {
  text-color purple
}

UICollectionView > UICollectionViewCell UILabel.title {
  font 20
}

我们通过nesting方式将view hierarchies表达成这样方式

UICollectionView {
  background-color #a2a2a2
  
  > UICollectionViewCell {
    clips-to-bounds NO
    
    UILabel {
      text-color purple
      
      &.title {
        font 20
      }
    }
  }
}
Variables

Classy让你通过定义variables来将多个相同的style property值存储以便共享。Variable命名规则如下:

  • 必须以大小写字母$符号开头
  • 可以包含_-或任何字母数字
// prefix with ' $ ' to help distinguish variables
$brand-color = #e1e1e1

// OR not
insets = 5, 10, 5, 10

UIButton {
   background-color $brand-color
   contentEdgeInsets insets
   background-image[state:selected] bg_button insets
}

最后官方还提供一个实例来解释具体如何使用:Custom Views Example

ClassyLiveLayout

ClassyLiveLayout通过结合Classy stylesheets与Masonry一起使用,能够在运行的模拟器中微调Auto Layout约束实时显示效果的工具。

ClassyLiveLayout一个核心category:UIView+ClassyLayoutProperties,在UIView定义以下属性:

@property(nonatomic, assign) UIEdgeInsets cas_margin;
@property(nonatomic, assign) CGSize cas_size;

// shorthand properties for setting only a single constant value
@property(nonatomic, assign) CGFloat cas_sizeWidth;
@property(nonatomic, assign) CGFloat cas_sizeHeight;

@property(nonatomic, assign) CGFloat cas_marginTop;
@property(nonatomic, assign) CGFloat cas_marginLeft;
@property(nonatomic, assign) CGFloat cas_marginBottom;
@property(nonatomic, assign) CGFloat cas_marginRight;

cas_margincas_size分别表示UI元素的位置和大小,而其余的属性都是对两个属性进一步细分。我们可以从stylesheets中访问style properties来定义constraints布局,做到将数据与代码分离,有利于修改和复用代码。

UIView.blue-box {
    cas_size: 80 100
    cas_margin-top: 60
    cas_margin-left: 50
}

UIView.red-box {
    cas_size-width: 120
    cas_margin-left: 20
}

我们可以在updateConstraintsupdateViewConstrains定义布局时引用style properties

- (void)updateViewConstraints {
  [super updateViewConstraints];

  [_blueBoxView mas_updateConstraints:^(MASConstraintMaker *make) {
      make.width.equalTo(@(_blueBoxView.cas_size.width));
      make.height.equalTo(@(_blueBoxView.cas_size.height));
      make.top.equalTo(@(_blueBoxView.cas_margin.top));
      make.left.equalTo(@(_blueBoxView.cas_margin.left));
  }];

  [_redBoxView mas_updateConstraints:^(MASConstraintMaker *make) {
      make.width.equalTo(@(_redBoxView.cas_size.width));
      make.height.equalTo(_blueBoxView);
      make.top.equalTo(_blueBoxView);
      make.left.equalTo(_blueBoxView.mas_right).with.offset(_redBoxView.cas_margin.left);
  }];
}

当定义view layouts时,将Auto Layout的constraints都放在stylesheets中实时加载(Live reload)。如果你修改constraints,无需重新编译、构建和运行模拟器便能实时看到修改后的效果。

示例工程

配置工程

由于需要引用Masonry,Classy和ClassyLiveLayout,Podfile配置如下:

pod 'Masonry', '~> 0.6.1'
pod 'Classy', '~> 0.2.4'
pod 'ClassyLiveLayout', '~> 0.6.0'

编写代码

1. 添加stylesheet.cas文件到工程

当安装好Masonry,Classy和ClassyLiveLayout后,第一次运行项目会出现没有stylesheet.cas文件错误:


No stylesheet.cas file error.png

只要向工程添加空的stylesheet.cas文件即可。


Create stylesheet.cas file.png
2. 创建LiveView类,该类继承SHPAbstractView
Create LiveView inherit SHPAbstractView.png
ViewController创建LiveView对象,然后被self.view引用。 Setup root view in ViewController.png
当编译运行时,在SHPAbstractView.h由于找不到UIView出现编译错误。
SHPAbstractView Compile error.png
只需引入UIKit便可以解决,但运行一下应用程序,出现一下错误:
Must override methods.png
主要原因是任何自定义UIView继承SHPAbstractView都需要override两个方法:- (void)addSubviews- (void)defineLayout,我们可以查看SHPAbstractView的源码可知: SHPAbstractView Source Code .png
所以只要在LiveView.m文件覆盖两个方法即可
#pragma mark - Add subviews and define layout
- (void)addSubviews
{
}

- (void)defineLayout
{
}
3. LiveView类设计

LiveView主要由包含redBoxViewblueBoxView两个属性,redBoxView表示红色方块,blueBoxView表示蓝色方块。

#import "SHPAbstractView.h"

@interface LiveView : SHPAbstractView

@property (strong, nonatomic) UIView *redBoxView;
@property (strong, nonatomic) UIView *blueBoxView;

@end

4. LiveView类实现

由于SHPAbstractView类如何初始化View已经做了处理,暴露两个接口- (void)addSubviews-(void)defineLayout分别处理构建view hierarchy和定义布局,子类只要覆盖SHPAbstractView这两个方法就可以创建LiveView了。
但是我们将Auto Layout的constraints都放在stylesheets中实时加载(Live reload),即放在本工程的stylesheet.cas文件,将布局数据和布局代码分离。

UIView.redBox {
    cas_marginTop 50
    cas_marginLeft 20

    cas_size 100 100
}

UIView.blueBox {
    cas_marginTop 50
    cas_marginRight -20

    cas_size 100 100
}

有了constraints数据后,便可以在代码布局:

@implementation LiveView

#pragma mark - Add subviews and define layout
- (void)addSubviews
{
    self.backgroundColor = [UIColor whiteColor];
    [self addSubview:self.redBoxView];
    [self addSubview:self.blueBoxView];
}

- (void)defineLayout
{
    [self.redBoxView mas_updateConstraints:^(MASConstraintMaker* make){
        make.top.equalTo(@(self.redBoxView.cas_marginTop));
        make.left.equalTo(@(self.redBoxView.cas_marginLeft));
        make.width.equalTo(@(self.redBoxView.cas_sizeWidth));
        make.height.equalTo(@(self.redBoxView.cas_sizeHeight));
    }];
    
    [self.blueBoxView mas_updateConstraints:^(MASConstraintMaker *make){
        make.top.equalTo(@(self.blueBoxView.cas_marginTop));
        make.right.equalTo(@(self.blueBoxView.cas_marginRight));
        make.width.equalTo(@(self.blueBoxView.cas_sizeWidth));
        make.height.equalTo(@(self.blueBoxView.cas_sizeHeight));
    }];
}

#pragma mark - Lazy initialization
- (UIView*)redBoxView
{
    if (!_redBoxView) {
        _redBoxView = [UIView new];
        _redBoxView.cas_styleClass = @"redBox";
        _redBoxView.backgroundColor = [UIColor redColor];
    }
    
    return _redBoxView;
}

- (UIView*)blueBoxView
{
    if (!_blueBoxView) {
        _blueBoxView = [UIView new];
        _blueBoxView.cas_styleClass = @"blueBox";
        _blueBoxView.backgroundColor = [UIColor blueColor];
    }
    
    return _blueBoxView;
}
5. 模拟器支持Live Reload

为了启用Live Reload,你需要指定stylesheet路径,并且只运行在模拟器上。

Support Live Reload.png

此时效果:

Live Change.gif
6. 分离样式文件

由于有网友提出这样一个问题:如果所有view的样式都放在同一个stylesheet.cas文件,会让stylesheet.cas文件繁杂,并且当多个人协同开发时,不易于合并代码,所以有必要将样式文件分离到多个文件中。

  1. 创建variable.cas文件,并将redBox对应UIView的样式放在variable.cas文件中。

    variable.cas file.png
  2. stylesheet.cas样式文件使用@import指令引用variable.cas文件

stylesheet.cas file.png

最后效果

Live Change 1.gif Live Change 2.gif

示例代码存放地址:LiveAutoLayout

总结

之前手写UI代码每次更改一般都要重新编译、构建和运行模拟器才能看到效果,但结合使用Masonry,Classy和ClassLiveLayout之后,告别这个费时过程,极大地提高开发速度;不仅如此,我们将Auto Layout的constraints都放在stylesheets中实时加载(Live reload),将布局数据和布局代码分离,使得代码更加复用和维护。Classy还提供三种避免重复方法:Grouping, Nestting和Variable,尽可能复用样式数据。
这是本人第一次编写技术博客,可能有很多错误和漏洞,希望大家多多指点,也希望这篇文章能够帮助到大家。

扩展阅读

相关文章

网友评论

  • coooliang:UIView.redBox 中使用cas_marginRight没有反应为什么?只能用left??
  • 某非著名程序员:18年了,看似强大,这个有人用吗?
  • 星期六下午火锅:您好 classy 有没有对于swift的项目 实用snpkit 布局的呢
  • 谢谢生活:楼主很有爱,感谢楼主分享好东西……
  • 秒赞不是偶然:cas 文件里面能获取到屏幕的高度 和宽度吗
  • Xezun:这玩意的效率如何?
    Xezun:@mlibai 主要是性能
    Sam_Lau:@mlibai 一般般
  • 36bb35d9d1d7:https://github.com/johnno1962/injectionforxcode
    这个插件可以实时更新修改结果
  • 小凡凡520:这么强大的Masonry 竟然没有用过
  • 低吟浅唱1990:下载了demo 但是没有博客上面的效果
    不知哪里出错了
  • e2efcfc2a55a:写的很棒!
  • LeoAu:Classy怎样控制字体粗细 font bold
  • 飞行的孤独员FG:你好,请问代码引用的黄色背景是怎么弄的啊 :joy:
    Jisen:@飞行的孤独员FG markdown编辑
  • Eddie_Zys:受用,赞一个强大的楼主。
  • ZsIsMe:受到您的文章的启发,我发现可以使用IB_DESIGNABLE和Masonry结合的方法,在xib上实时显示Masonry布局代码,我也在简书上分享了,不过水平有限,望指教一下。 :smile:
    http://www.jianshu.com/p/e4accdbfd841
    Sam_Lau:@ZsIsMe 👍🏻👍🏻👍🏻
  • LeoAu:我自己项目上试了一遍,虽然是分离了样式代码,方便维护,但同样文件也是增加了不少,增加了一个对应的LiveView.h & LiveView.m文件,然后在controller里再调用

    > 我认为addSubviews和defineLayout可以写在controller里面,这样就不用维护太多文件,我尝试过在LiveView里面添加delegate,让addSubviews里面去执行这个delegate在controller里实现delegate的方法,可惜失败了,正在研究其原因。当然如果不需要ClassyLiveLayout的话,LiveView大可不必生成
    Sam_Lau:@LeoAu 哈哈,👍🏻👍🏻👍🏻
    LeoAu:@Sam_Lau 确实如您所言,Controller不应该承担画UI的职责,我现在是代码UI+xib混合,一些复杂的界面用代码来维护更加方便和清晰,一些简单固定的界面则直接使用xib(拖几个icon也写一堆代码)。所以也想和博主多交流这方面的经验 :grin:
    Sam_Lau:@LeoAu controller不应该承担画UI的职责,应该交给单独一个view做,当UI复杂时,controller会变得臃肿且不易维护。而且,当view中有些组件可以复用时,更加容易分离出来,而不需要改动controller的代码
  • Sam_Lau:@FAB 对的,但是你在reveal改完之后,还需要在代码还
  • f3f504fa1629:reveal embedded in也能实时改啊
  • 5a419db84a85:照着做,没有实现效果呀?!!!
    5a419db84a85:@5a419db84a85 可以了,尴尬……
  • Sam_Lau:@是我始终拒绝成长吗 应该能,不过没试过,你可以尝试一下
  • 是我始终拒绝成长吗:能不能修改颜色呢
  • DavidLam:既然都用到CSS了还要再结合 auto layout 感觉好蛋疼。
    如果UX的图标注得比较好,感觉好像就没什么必要了。
  • 0edc44a214a9:确实挺不错的
  • Sam_Lau:@周大同 你加我qq吧,784854572
  • datongzhou:@Sam_Lau 😄,不好意思,我还是不会,我的做法是创建一个一般文件,改后缀,那么问题来了,文件的后缀能改,结构不能改啊,还有xcode不能编写他啊,唉,小白,望大神指点
  • 渡云雨:如果不使用Pods 怎么办?
  • xclidongbo: @Sam_Lau 2个,项目着急的话,领导也会加入。
  • Sam_Lau:@xclidongbo 你们公司多少人做一个项目?
  • Sam_Lau:@xclidongbo 每个人的观点和做事方式都可能不同,最重要的是选择最适合自己,同时能提高开发效率就行,没必要强迫,😁😁😁
  • xclidongbo: @Sam_Lau 恩,是的。我不知道你们怎么做项目的。我们公司要求快。恨不能一个项目两到三周搞定。很难想像,一个没有代码补全的东西用到项目里,会给其它同事造成多大麻烦。 我说的可能不中听。另外我的观点也不一定正确。不过非常感谢,你能给大家介绍这么优秀的方式来实时展现UI.
    36bb35d9d1d7:@xclidongbo 可以参考这个代码补全插件https://github.com/poboke/TweakAutocomplete
    xclidongbo:@iOSPro 额,有插件编写的相关教程没?
    余不悟:@xclidongbo 我觉得像代码补全的话,既然你们用得多的话,为什么不写一个代码补全插件.
  • Sam_Lau:@xclidongbo 你是指因为没有代码补全而不成熟吗?
  • xclidongbo: @Sam_Lau 谢谢回复。
  • xclidongbo: @Sam_Lau 看来这种方式在项目开发中还是不成熟。
  • xclidongbo: @Sam_Lau 看来这种方式在项目开发中还是不成熟。
  • Sam_Lau:@xclidongbo 暂时没有暂时没有
  • xclidongbo:我很想知道,stylesheet.cas文件的代码补全和高亮怎么做?
  • Sam_Lau:@MeiganFang 不过,我还是建议在简书讨论,因为这样的话,大家都可以参与讨论
  • Sam_Lau:@MeiganFang 我很少上qq,你在我的主页加我微信吧
  • Sam_Lau:@周大同 跟创建普通文件差不多啊
  • datongzhou:版主,stylesheet.cas这个文件怎么创建啊 ?
    swif的嘛?
  • Sam_Lau:@aaa13413345005 添加什么?
  • 7c31fa924ef4:话说怎么在现有的workspace里面添加这些啊······
  • Sam_Lau:@wingsrao 互相学习吧 :stuck_out_tongue_winking_eye:
  • wingsrao:写得真的不错,向你学习!
  • a0aff3927ae1:感谢分享
  • MeiganFang:博主,这样做,耦合度是否会增加?加个qq 349438233 交流下。 另外刚发现简书登录bug,点登录跳转到简书首页 :sweat:
  • 06067cf1c942:@Sam_Lau 已看到新工程实现方式,谢谢 :smile:
  • 4c93ece99504:web css live load的思路那,值得学习下。
  • dd8a1077569c:masonry 引入我的工程以后 发现 有些 手动 布局代码 报错了 感觉和masattribe冲突了 这种情况遇见过吗
  • Sam_Lau:@雷子恒 博客以及LiveAutoLayout已经更新工程,希望能帮助到你
  • Sam_Lau:@雷子恒 我可以在LiveAutoLayout更新工程,然后你可以参考如何编写!
  • Sam_Lau:@雷子恒 其实你可以创建另一个样式文件,然后在stylesheet.cas引用它,这样就可以分离多个view的样式,同时也可以多人协作开发。
  • 06067cf1c942:一个项目只允许有一个stylesheet.cas吧?那我所有界面的布局设置都写在这个文件里,那这个文件内容会很大啊,后期也不好查找具体哪个控件,文件大了解析速度上也要消费更长时间。如果可以一个界面对应一个cas文件就好了
  • 998eddf8739d:感谢分享
  • CarryIT:给力啊!开启学霸模式!
  • 嘉言火:不错
  • Sam_Lau:@HTC 有什么想法随时欢迎讨论
  • iHTCboy:内容巨大,慢慢吞,谢谢分享!
  • Sam_Lau:有空可以学习一下
  • Sam_Lau:@SuperY 那你是使用原生的NSLayoutConstraint吗?还是选用其他Auto Layout库
  • 6093b85fc556:Masonry 停止维护了 :flushed:
    4ef7e44e7a90:@SuperY 是的.但是原作者又搞了一个https://github.com/SnapKit/SnapKit
  • Huangyuanming:好给力,好好学习

本文标题:实时显示iOS编写UI代码效果

本文链接:https://www.haomeiwen.com/subject/lxaufttx.html