总结一下最近工作中的问题170309

新起得项目,啥都得重新来弄,别的组做的组件也没法搬过来用,只能自己淌水重写。到现在,大问题还没发现,小问题不少,值得记录的细节也有一些,这篇就权当做个笔记,加深一下印象吧。

Nimbus

项目中用到的一个Three20的替代库Nimbus,对于表视图的页面来说还是非常的强大的,一言两语也说不清楚,后面单开来说吧。

Protobuf数据格式

我们这边跟后台数据交互用的是Google的Protobuf,这是一种精简的数据传输协议,生成的字节集数据要比json小很多。官方的github仓库:Protobuf详细介绍编译环境的安装

TableViewCell选中时的背景高亮

这个Apple已经给做了,可以设置selectedBackgroundView这个属性,如在创建cell的时候:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *reusefulIdentifier = @"reusefulIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reusefulIdentifier];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reusefulIdentifier];
        cell.selectedBackgroundView = [[UIView alloc] initWithFrame:cell.bounds];
        cell.selectedBackgroundView.backgroundColor = [UIColor redColor];
    }
    return cell;
}

或者干脆点,建一个Cell的基类,如:

@implementation FTFBaseTableViewCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style 
              reuseIdentifier:(NSString *)reuseIdentifier {
    if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) 
    {
        self.backgroundColor = kFTFContentBgColor;
        // 解决cell高亮、选择后的背景色
        self.selectedBackgroundView = [[UIView alloc] initWithFrame:self.bounds];
        self.selectedBackgroundView.backgroundColor = [UIColor redColor];   
        [self initlization];
    }
    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    self.selectedBackgroundView.frame = self.bounds;
}
@end

注意

  • selectedBackgroundView对于UITableViewStylePlain类型默认是nil,需要自己创建一个并赋值给他,对于UITableViewStyleGrouped类型则不为nil。

    这个view被加载在backgroundView之上,在所有其他view的下方。

  • 如果要设置这个属性的话,请设置cell的selectionStyleUITableViewCellStyleDefault类型,如果为UITableViewCellSelectionStyleNone,那么选择的效果将会没有。

TableViewCell选中的时候上面的组件背景色变了

如下图:

问题是在cell高亮状态下得时候,US这个label的背景色就会消失掉,我想这个问题应该都遇到过。刚遇到这个问题的时候,看网上也有不少人说过这个,但是解决的方式也是各有千秋。而我则是对Category更偏爱一点。

我的处理方式是,使用runtiem的方式对每个会改变的组件都添加一个cachedColor属性,在设置比如背景色属性的时候,顺便设置一下这个属性,那么就会解决这个问题了。

如下,创建一个cell的基类,然后添加代码:

@implementation FTFBaseTableViewCell
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
    [self configOriginalBackgroundColorForView:self];
}
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
    [super setHighlighted:highlighted animated:animated];
    [self configOriginalBackgroundColorForView:self];
}
- (void)configOriginalBackgroundColorForView:(UIView *)view {
    for (id obj in view.subviews) {
        if ([obj isKindOfClass:[UIView class]]) {
            UIView *subview = (UIView *)obj;
            if (subview.cachedColor) {
                subview.backgroundColor = subview.cachedColor;
            }
            [self configOriginalBackgroundColorForView:obj];
        }
    }
}
@end

使用的时候:

_countrySymbol.cachedColor = kFTFButtonBgColorBlue;
_countrySymbol.backgroundColor = kFTFButtonBgColorBlue;

这样的话,再在高亮的状态下,_countrySymbol的背景该是怎样就还是怎样了。

UISearchBar默认的灰色背景框

UISearchBar放到navigationItem.titleView上得时候,会默认的加一个灰色的背景框,这点很讨厌,如图:

这时候只需要设置searchBarStyleUISearchBarStyleMinimal即可,不过需要注意的是,这个时候UISearchBar会是透明的,没有背景了,所以需要再给他设置一个背景就行了。

@implementation FTFSearchBar
- (instancetype)init {
    return [self initWithFrame:CGRectMake(0, 0, kSCREEN_WIDTH, 44)];
}
- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.searchBarStyle = UISearchBarStyleMinimal;
        self.searchTextPositionAdjustment = UIOffsetMake(5, 0);
    }
    return self;
}
- (void)setBackgroundColor:(UIColor *)backgroundColor{
    _backgroundColor = backgroundColor;
    if (backgroundColor) {
        UIImage *backgroundImage = [UIImage imageWithColor:backgroundColor size:CGSizeMake(10, 30)];
        backgroundImage = [backgroundImage roundedImageWithRadius:4 cornerMask:FTFImageRoundedCornerTopLeft | FTFImageRoundedCornerTopRight | FTFImageRoundedCornerBottomRight | FTFImageRoundedCornerBottomLeft];
        [self setSearchFieldBackgroundImage:backgroundImage forState:UIControlStateNormal];
    }
}
@end

效果如下:

系统的menu菜单

弹出效果如下:

刚开始在网上找了一下代码,都是只有添加菜单项的,然后再显示,但是最后怎么也弹不出来,郁闷的无以言表,最后才发现,少写了几个方法,完整的如下:

  • 创建UIMenuController
UIMenuController *menuController = [UIMenuController sharedMenuController];
UIMenuItem *deleteItem = [[UIMenuItem alloc] initWithTitle:@"删除" action:@selector(deleteItem)];
UIMenuItem *bringTopItem = [[UIMenuItem alloc] initWithTitle:@"置顶" action:@selector(bringToTop)];
[menuController setMenuItems:@[deleteItem, bringTopItem]];
  • 实现UIResponder的几个方法
-(BOOL)canBecomeFirstResponder{
    return YES;
}
//是否可以接收某些菜单的某些交互操作,如果返回NO,则不会显示在菜单里
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender{
    if (action == @selector(deleteItem) || action == @selector(bringToTop)) {
        return YES;
    }
    return NO;
}
  • 最后就是显示
- (void)showMenu:(UILongPressGestureRecognizer *)gesture {
    if (![UIMenuController sharedMenuController].menuVisible) {
        CGPoint tapLocation = [gesture locationInView:self];
        [self becomeFirstResponder];
        [[UIMenuController sharedMenuController] setTargetRect:CGRectMake(tapLocation.x, tapLocation.y, 1, 1) inView:self];
        [[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];
    }
}

CoreData创建Entity实体类

在Xcode8以前的时候,直接File -> New -> File...,然后选择CoreData的Entity就能创建了,但是现在却没有了这个选项。

可以先在左侧的文件列表中选中你的*****.xcdatamodeld文件,然后在菜单栏中Editor -> Create NSManagedObject SubClass ...,在弹出的窗口中选择你的Entity Model就就可以了。

需要注意的是,这样创建的Entity文件的语言貌似是Swift,可以先选择****.xcdatamodeld文件,然后在右侧的文件属性栏中选择一下你要的语言即可,如图:

不过Xcode8有个bug,新建完以后运行会报如下错误:

ld: 2 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

这时候可以参考这个来修改关于XCode8使用Coredata建立实体类的问题?–知乎

Directory not found

如下图:

解决如下:

  1. 选择工程
  2. 选择你的target
  3. Build Settings
  4. 搜索到 Framework Search PathsLibrary Search Paths这两项,然后删除警告的路径即可,如图删除这两个警告的选项即可:

Cannot assign to ‘self’ outside of a method in the init family

这个问题是在重新的时候出现的,如下:

总结一下最近工作中的问题170309

这个是由于粗心,- (instancetype)initwithStyle:(UITableViewStyle)style这里init后的部分没有以大写字母开头。

1 comment

发表评论

电子邮件地址不会被公开。