首先跑程序出来,到达那个图片的位置,在控制台可以看到它的上一层的路径,在Finder点进去之后前往文件夹查看,核对的时候打开程序进行核对。
// AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
//加进去
[[CKCurrencyManager sharedInstance] addendCurrencyWithCount:1000];
下载成功后的界面从cmplete按钮,变成一个View,这个View上有两个标签和一个image。
首先第一步就是创建一个包含三个子控件view,不能创建成controller(不好往项目里加)。代码在CKDownloadFinishView.m中
3.1.1 属性声明
@property (nonatomic) UIImageView *imageView;
@property (nonatomic) UILabel *titleLabel;
@property (nonatomic) UILabel *subTitleLabel;
3.1.2 三个get方法
- (UIImageView *)imageView {
if (nil == _imageView) {
_imageView = [UIImageView new];
_imageView.image = [UIImage imageNamed:@"ic_Downloaded"];
}
return _imageView;
}
- (UILabel *)titleLabel {
if (nil == _titleLabel) {
_titleLabel = [UILabel new];
_titleLabel.text = NSLocalizedString(@"ck_button_downloaded", nil);
_titleLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:16.0f];
NSString *labelText = _titleLabel.text;
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:labelText attributes:@{NSKernAttributeName:@(0.75)}];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [labelText length])];
_titleLabel.attributedText = attributedString;
[_titleLabel sizeToFit];
}
return _titleLabel;
}
- (UILabel *)subTitleLabel {
if (nil == _subTitleLabel) {
_subTitleLabel = [UILabel new];
_subTitleLabel.text = NSLocalizedString(@"ck_download_finish_subTitle", nil);
_subTitleLabel.font = [UIFont fontWithName:@"Helvetica" size:12.0f];
NSString *labelText = _subTitleLabel.text;
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:labelText attributes:@{NSKernAttributeName:@(0.56)}];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [labelText length])];
_subTitleLabel.attributedText = attributedString;
[_subTitleLabel sizeToFit];
}
return _subTitleLabel;
}
3.1.3 初始化
- (instancetype)init {
if (self = [super init]) {
self.backgroundColor = [UIColor whiteColor];
[self addSubview:self.imageView];
[self addSubview:self.titleLabel];
[self addSubview:self.subTitleLabel];
}
return self;
}
3.1.4 更新约束
- (void)updateConstraints {
[super updateConstraints];
[self.imageView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.mas_left).offset(20.0f);
make.centerY.equalTo(self.mas_centerY);
}];
[self.titleLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.mas_top).offset(5.0f);
make.centerX.equalTo(self.mas_centerX);
}];
[self.subTitleLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.titleLabel.mas_bottom).offset(5.0f);;
make.bottom.equalTo(self.mas_bottom).offset(-5.0f);
make.centerX.equalTo(self.mas_centerX);
}];
}
这个是在CKCoolFontWindowController.m中出现的
3.2.1 声明属性
@property (nonatomic) CKDownloadFinishView *downloadFinishView;
3.2.2 写一个get方法
- (CKDownloadFinishView *)downloadFinishView {
if (nil == _downloadFinishView) {
_downloadFinishView = [CKDownloadFinishView new];
_downloadFinishView.hidden = YES;
}
return _downloadFinishView;
}
3.2.3 在loadView中加入自己写好的view
loadView方法是用来负责创建UIViewController的view。
这里要按照这个出现的先后顺序和覆盖去决定这个自己的view放在哪里,因为是在支付确认后弹出的,所以位置要放在它们两个后面。又因为这个view也在弹窗上面,所以需要把这个view添加到contentView上面。
[self.view addSubview:self.contentView];
······
[self.contentView addSubview:self.paymentButton];
[self.contentView addSubview:self.currencyButton];
[self.contentView addSubview:self.downloadFinishView];
3.2.4 相对布局
因为要覆盖掉之前的支付按钮,所以这个view的大小,至少要比按钮大。
而且位置也要放好,这个相对位置指的是和之前的某个标签的相对位置。
[self.paymentButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.uppercasesLabel.mas_bottom).offset(35.0f);
make.left.equalTo(self.contentView.mas_left).offset(14.0f);
make.right.equalTo(self.contentView.mas_right).offset(-14.0f);
make.height.mas_equalTo(46.0f);
}];
[self.currencyButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.paymentButton.mas_bottom).offset(16.0f);
make.left.equalTo(self.contentView.mas_left).offset(14.0f);
make.right.equalTo(self.contentView.mas_right).offset(-14.0f);
make.height.mas_equalTo(46.0f);
}];
[self.downloadFinishView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.uppercasesLabel.mas_bottom).offset(35.0f);
make.left.equalTo(self.contentView.mas_left).offset(14.0f);
make.right.equalTo(self.contentView.mas_right).offset(-14.0f);
}];
3.2.5
在合适的地方让它出现就可以了
self.downloadFinishView.hidden = NO;
//必须加上执行代理方法回调
if ([self.delegate respondsToSelector:@selector(installDidcompleteForModel:)]) {
[self.delegate installDidcompleteForModel:self.model];
}
这里插一句在调试这个弹窗位置可以通过这个功能来确认自己的想法有没有出错。
./VersionChangeScript.sh -n
1、声明一个未读的属性,这里面以Diy为例子
@property (nonatomic) UIView *unreadMessageDiyView;
2、给该属性一个get方法
这里可以直接输入属性名字就可以看到代码提示
如果这个view不存在的话,就初始化新建一个
设置好它的形状和背景并返回
- (UIView *)unreadMessageDiyView {
if (nil == _unreadMessageDiyView) {
_unreadMessageDiyView = [UIView new];
_unreadMessageDiyView.layer.cornerRadius = 2.5f;
_unreadMessageDiyView.backgroundColor = [UIColor redColor];
}
return _unreadMessageDiyView;
}
3、判断这个红点是否被点击,设置函数
三个形式
//CKTools.m
(1)是否超过12小时或者24小时,如果是的话就出现
+ (BOOL)unreadMessageForTimeDay {
NSDate *lastDate = [[NSUserDefaults standardUserDefaults] objectForKey:@"unreadMessageTime"];
if (nil == lastDate) return YES;
NSTimeInterval dayTime = [[NSDate date] timeIntervalSinceDate:lastDate];
if (dayTime > 12 * 60 * 60) {
return YES;
}
return NO;
}
(2)是否被点击过
+ (BOOL)unreadMessageForSticker{
return [[NSUserDefaults standardUserDefaults] boolForKey:@"unreadMessageForSticker"];
}
(3)需要判断某个值为真假才确定是否要添加红点
+ (BOOL)unreadMessageForAddAvator{
return [[[NSUserDefaults alloc] initWithSuiteName:AppGroupsNameString] boolForKey:@"changeUnreadMessageStatusForAvatarAddend"];
}
4、清除这个红点
(1)是否超过12小时或者24小时,如果是的话就取消红点
+ (void)unreadMessageClearDiy{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"unreadMessageForDiy"];
}
(2)是否被点击过,点击过的话就取消红点
+ (void)unreadMessageClearSticker{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"unreadMessageForSticker"];
}
5、在这个大的TopBar里面进行初始化
由于这个Diy菜单按钮是在menuContainerView里面,因此要是添加的话也应该是在这里。
//如果新添加过的avator,那么unreadMessageForAddAvator返回的值为true
if ([CKTools unreadMessageForAddAvator]) {
//[self.menuContainerView addSubview:self.unreadMessageThemeView];
//[self.menuContainerView addSubview:self.unreadMessageDiyView];
//如果未读,也就是unreadMessageForSticker == NO
if(NO == [CKTools unreadMessageForSticker]){
//将unreadMessageForSticker设置为YES,红点出现
[CKTools unreadMessageClearSticker];
[self.menuContainerView addSubview:self.unreadMessageStickerView];
}
}
if ([CKTools unreadMessageForTimeDay]) {
//unreadMessageForSticker为NO,代表sticker没有红点
if(NO == [CKTools unreadMessageForSticker]){
[self.menuContainerView addSubview:self.unreadMessageDiyView];
}
}
if(NO == [CKTools unreadMessageForAvator]) {
//[self.menuContainerView addSubview:self.unreadMessageAvatarsView];
}
1、写出一个缩放效果的函数
-(CABasicAnimation *)scale:(NSNumber *)multiple withOrgin:(NSNumber *)orginMultiple durTimes:(float)time Rep:(float)repertTimes{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation.fromValue = multiple;
animation.toValue = orginMultiple;
animation.autoreverses = YES;
animation.repeatCount = repertTimes;
animation.duration = time;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
return animation;
}
这里要注意,想要回到图片原始位置一定要
animation.removedOnCompletion = YES;
1、找到想要添加心脏跳动的按钮位置,在里面添加上这个特效
- (UIButton *)avatarsButton {
if (nil == _avatarsButton) {
_avatarsButton = [UIButton buttonWithType:UIButtonTypeCustom];
_avatarsButton.contentMode = UIViewContentModeScaleAspectFit;
[_avatarsButton addTarget:self action:@selector(actionForAvatarsButton:) forControlEvents:UIControlEventTouchDown];
[_avatarsButton.layer addAnimation:[self scale:[NSNumber numberWithFloat:1.2f] withOrgin:[NSNumber numberWithFloat:1.0f] durTimes:0.3f Rep:3] forKey:nil];
}
return _avatarsButton;
}
2、添加特效需要注意这几个参数
(1)缩放大小的倍数
numberWithFloat:9.0f
(2)缩放的速度
durTimes:0.3f
(3)节拍:
Rep:3
3、冬哥写的心脏跳动
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation.fromValue = [NSNumber numberWithFloat:1.0f];
animation.toValue = [NSNumber numberWithFloat:1.4f];
//animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
animation.duration = .3f;
animation.removedOnCompletion = NO;
animation.repeatCount = 4;
animation.autoreverses = YES;
animation.fillMode = kCAFillModeForwards;
[_stickerButton.layer addAnimation:animation forKey:nil];
iOS
LLDB
po exp bt
// 地址转代码
image lookup --address 0x0000000104c25550
//Oc转c++指令
xcrun -sdk iphonesimulator clang -rewrite-objc
xcrun -sdk iphoneos clang -rewrite-objc
__attribute__((objc_subclassing_restricted)) //无法继承
__attribute__((objc_requires_super)); //子类实现必需调用父类
//泛型
<__contravariant ObjectType>
<__covariant ObjectType>
DYLD_PRINT_STATISTICS 打印启动用时
DYLD_PRINT_STATISTICS_DETAILS
// 内存泄漏
instruments -> leaks -> 开始检测内存泄露
leaks -> call Tree -> lnvert Call Tree , Hide System Libraries
// 让单个文件arc设置
-fno-objc-arc, -fobjc-arc
// 添加pch文件
Build settings ->Search Paths ->Header Search Paths
// 颜色宏
#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
// encoding编码转换
[str stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]
//去除两端空格
NSString *temp = [textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
//去除两端空格和回车
NSString *text = [temp stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// 获取view所在windows的绝对位置,无关view所在层级关系
CGRect rect = [view convertRect:CGRectMake(0, 0, view.bounds.size.width, view.bounds.size.height) toView:[[UIApplication sharedApplication] keyWindow]];
// 获取系统版本
NSString *version = [[UIDevice currentDevice] systemVersion];
// 获取屏幕大小
CGRect rect = [[UIScreen mainScreen] bounds];
// 将一个图片按指定像素内的部分拉伸
[UIImage resizableImageWithCapInsets:UIEdgeInsetsMake(top, left, bottom, right)];
// 在程序中的任意位置获取本应用程序的appDelegate
id appDelegate = [[UIApplication sharedApplication] delegate];
// 状态栏下载图标
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
// 获取应用程序沙盒的Documents目录
NSString * path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) objectAtIndex:0];
NSString * path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
// 获取文件在沙盒中的路径
NSString * path = [[NSBundle mainBundle] pathForResource:@"fileName" ofType:@"exteName"];
// 获取控件自身所在的viewController
- (UIViewController *)viewController {
for (UIView* next = [self superview]; next; next = next.superview) {
UIResponder *nextResponder = [next nextResponder];
if ([nextResponder isKindOfClass:[UIViewController class]])
return (UIViewController *)nextResponder;
}
return nil;
}
// C结构体与OC对象之间的转换
NSValue * value = [[NSValue alloc]initWithBytes:&args objCType:@encode(struct type)];
[value getValue:&args];
//获取一个对象的Class
class_getInstanceMethod()
//替换两个方法
method_exchangeImplementations()
//创建定时器
NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(runTime) userInfo:nil repeats:YES];
[timer invalidate]; // 销毁定时器
[timer setFireDate:[NSDate distantFuture]];// 暂停定时器
[timer setFireDate:[NSDate distantPast]]; // 重启定时器
//多数据同时归档到一个文件中
NSKeyedArchiver * archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:outData];
[archiver encodeObject:obejct forKey:@"key"];
[archiver finishEncoding];
[outDatadata writeToFile:path atomically:YES];
// 解档
NSKeyedUnarchiver * unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:inData];
id object = [unarchiver decodeObjectForKey:@"key"];
// 视图层添加动画效果
库支持:QuartzCore/QuartzCore.h
CATransition * trans = [CATransition animation];
trans.type = @""; // fade渐隐,cameraIris相机,cube立体,moveIn移入,oglFlip翻转,pageCurl后翻,pageUnCurl前翻,push平移,suckEffect抽除,reveal移隐
trans.subtype = @"fromRight"; // fromLeft, fromRight, fromTop, fromBottom
trans.duration = 0.3f; // 动画所用时间
[view.layer addAnimation:trans forKey:nil]; // 添加到视图
// 视图层的layer
库支持:QuartzCore/QuartzCore.h
View.layer.shadowPath = [UIBezierPath bezierPathWithRect:View.bounds].CGPath; // 使用指定矩形获取贝尔曲线路径
View.layer.shadowOpacity = 0.8f; // 阴影透明度
View.layer.cornerRadius = 10; // 圆角
View.layer.masksToBounds = YES; // 剪切
#import "PremiumTermViewController.h"
#import
#import
@interface PremiumTermViewController ()<WKNavigationDelegate,WKUIDelegate>
将
UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
改为:
WKWebView *webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds];
将
[webView loadHTMLString:html baseURL:nil];
改为:
NSString *headerString = @" ";
[webView loadHTMLString:[headerString stringByAppendingString:html] baseURL:nil];
改完之后整体代码如下:
#import "PremiumTermViewController.h"
#import
#import
@interface PremiumTermViewController ()<WKNavigationDelegate,WKUIDelegate>
//@property (nonatomic, strong)WKWebView *webView;
@property (nonatomic, strong)UIButton *closeButton;
@end
@implementation PremiumTermViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self settingView];
}
- (void)settingView{
self.closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.closeButton setImage:[UIImage imageNamed:@"close_bound_btn"] forState:UIControlStateNormal];
[self.closeButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[self.closeButton setBackgroundColor:[UIColor clearColor]];
[self.closeButton addTarget:self action:@selector(clickClose) forControlEvents:UIControlEventTouchUpInside];
WKWebView *webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds];
NSString * htmlPath = [[NSBundle mainBundle] pathForResource:self.privacyFileName ofType:nil];
NSError * error;
NSString * html = [[NSString alloc] initWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:&error];
NSString *headerString = @" ";
[webView loadHTMLString:[headerString stringByAppendingString:html] baseURL:nil];
[self.view addSubview:webView];
[self.view addSubview:self.closeButton];
}
- (void)clickClose{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
[self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.view).offset(-10);
make.top.equalTo(self.view).offset(20);
make.width.mas_equalTo(35);
make.height.mas_equalTo(35);
}];
}
@end