imagemagick 图片压缩 修改hash
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew install imagemagick
find . -iname "*.png" -exec echo {} \; -exec convert {} {} \;
参考
静态方法
static void SimpleObjectExample() {
YYBook *book = [YYBook modelWithJSON:@" \
{ \
\"name\": \"Harry Potter\", \
\"pages\": 512, \
\"publishDate\": \"2010-01-01\" \
}"];
NSString *bookJSON = [book modelToJSONString];
NSLog(@"Book: %@", bookJSON);
}
布局
HandyFrame
队列
dispatch_queue_t queue = dispatch_queue_create("com.ios.refresh", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
[self ask_clubInfo:^{
dispatch_group_leave(group);
}];
dispatch_group_notify(group, queue, ^{
});
信号量
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (......) {
dispatch_async(quene, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
do....
dispatch_semaphore_signal(semaphore);
});
}
dispatch_async(quene, ^{
//最后执行
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
if(finishBlock)
{
finishBlock(YES,dataList);
}
dispatch_semaphore_signal(semaphore);
});
属性的synthesize dynamic
1、@property有两个对应的词,一个是@synthesize,一个是@dynamic。如果@synthesize和@dynamic都没写,那么默认的就是@syntheszie var = _var;
2、@synthesize的语义是如果你没有手动实现setter方法和getter方法,那么编译器会自动为你加上这两个方法。
3、@dynamic告诉编译器,属性的setter与getter方法由用户自己实现,不自动生成。(当然对于readonly的属性只需提供getter即可)。假如一个属性被声明为@dynamic var,然后你没有提供@setter方法和@getter方法,编译的时候没问题,但是当程序运行到instance.var =someVar,由于缺setter方法会导致程序崩溃;或者当运行到 someVar = var时,由于缺getter方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。
结构体定义
struct SpaceImg{
CGFloat img1_left;
CGFloat img1_right;
CGFloat img2_left;
CGFloat img2_right;
};
typedef struct SpaceImg SpaceImg;
XCode插件
@2x转@3x,imageAssets操作
系统音效
参考链接
Block定义
int(^myBlock)(int) = ^(int num){
return num * 7;
};
// 如果没有参数列表,在赋值时参数列表可以省略
void(^aVoidBlock)() = ^{
NSLog(@"I am a aVoidBlock");
};
添加QQ群助手
https://qun.qq.com/join.html?has_onekey=1
表格删除添加cell的时候跳动问题
链接
iOS11 self-sizing 默认开启 会自动计算cell的高度 contentsize和contentOffset会发生变化
self.tableView.estimatedRowHeight = 0;
self.tableView.estimatedSectionHeaderHeight = 0;
self.tableView.estimatedSectionFooterHeight = 0;
部分圆角
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(10, 10)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = rect;
maskLayer.path = maskPath.CGPath;
self.layer.mask = maskLayer;
iOS11 上scrollview布局向下偏移问题
automaticallyAdjustsScrollViewInsets 方法有调整
if (@available(iOS 11.0, *)) {
self.scrollV.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {
self.automaticallyAdjustsScrollViewInsets = NO;
}
CAAnimation 的keypath
例子
transform.scale = 比例轉換
transform.scale.x = 宽的比例轉換
transform.scale.y = 高的比例轉換
transform.rotation.z = 平面圖的旋轉
opacity = 透明度
margin=边框间隔?
zPosition = 平面图的位置
backgroundColor = 背景色
cornerRadius = layer的角度
borderWidth = 边框宽度
contents = 内容?
bounds = 大小?
contentsRect = 内容矩形
frame = 位置
hidden = 隐藏
mask = 标记
maskToBounds
position = 位置
shadowOffset = 阴影偏移?
shadowColor = 阴影颜色
shadowRadius = 阴影角度
动画结束状态不变
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
监听动画过程frame
链接
// 监听MyView
- (void)startWatchMyView {
[self stopWatchMyView];
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(watchMyViewAction)];
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
- (void)watchMyViewAction {
CALayer *presentationLayer = self.myView.layer.presentationLayer;
[self handleMaskViewWithMyViewFrame:presentationLayer.frame];
}
// 停止监听MyView
- (void)stopWatchMyView {
[self.displayLink invalidate];
self.displayLink = nil;
[self watchMyViewAction];
}
- (void)handleMaskViewWithMyViewFrame:(CGRect)myFrame {
// 下面是根据myFrame 进行其他相关view的绘制
[self.myView setNeedsDisplay];
// mask处理overlayView
self.overlayView.maskFrame = myFrame;
[self.overlayView setNeedsDisplay];
}
作者:AlienJunX
链接:https://www.jianshu.com/p/904d6ddee257
來源:
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Masonry安全区域
if (@available(iOS 11.0, *)) {
make.bottom.equalTo(self.view.safeAreaLayoutGuideBottom);
} else {
make.bottom.equalTo(self.view);
}
获取启动页图片
地址1
地址2
+ (UIImage *)getTheLaunchImage
{
CGSize viewSize = [UIScreen mainScreen].bounds.size;
NSString *viewOrientation = nil;
if (([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortraitUpsideDown) || ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortrait)) {
viewOrientation = @"Portrait";
} else {
viewOrientation = @"Landscape";
}
NSString *launchImage = nil;
NSArray* imagesDict = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"UILaunchImages"];
for (NSDictionary* dict in imagesDict)
{
CGSize imageSize = CGSizeFromString(dict[@"UILaunchImageSize"]);
if (CGSizeEqualToSize(imageSize, viewSize) && [viewOrientation isEqualToString:dict[@"UILaunchImageOrientation"]])
{
launchImage = dict[@"UILaunchImageName"];
}
}
return [UIImage imageNamed:launchImage];
}