阅读目录
1.键盘弹出隐藏通知.
- 检测一段代码运行时间的方法。
3.UILabel显示html文本
4.改变导航栏按钮的位置
5.实现文字和边框之间有间隔 的一种方式
6.去掉uitableviewcell的点击效果
7.tableView滚动到最下边的方法
8.去除 No Results 标签,需要设置UISearchDisplayController的delegate
9.子视图的层次关系控制
10.iOS开发中方法延迟执行的几种方式
11.从导航堆栈中删除viewcontrollers
12.自定义对象的深拷贝
13.IOS-- UIView中的坐标转换
14.UITextView 取消换行 文字自动向右滚动
15.iOS App 唤醒另一个App
16.Objective-C学习——中文URL编码和解码
17.dismissViewController跳转到RootViewController、跳转到指定ViewController
18.objcet-c中block的使用
19.ios UITableViewCell 左滑删除时,改变删除按钮背景颜色
20.状态栏的隐藏
21.打开模拟器沙盒路径:
22.照片保存到相册的三种方法
23.设置 UITableview 的间隔线
24.动态高度计算
25.restFul网络请求框架封装
26.UILabel 根据文本获取其 size
27.ios防止按钮重复点击事件
28.uitableview 设置 sectionHeader 不停留
29.使用Runtime完成归档与解档
30.点击提示框视图以外的其他地方时隐藏弹框
1. 键盘弹出隐藏通知
//注册监控键盘弹出的通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyBoardWillShow:)name:UIKeyboardWillShowNotification object:nil];
// 注册监控键盘隐藏的通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyBoardWillHidden:)name:UIKeyboardWillHideNotification object:nil];
-(void) keyBoardWillShow:(NSNotification*) notification
{
CGRect rect;
[noti.userInfo[UIKeyboardFrameEndUserInfoKey] getValue:&rect];
self.hidden = NO;
if (self.ofViewController.view) {
self.frame = CGRectMake(0, self.ofViewController.view.height-rect.size.height -self.height, self.width, self.height);
}
}
2.检测一段代码运行时间的方法。
NSDate* tmpStartData = [[NSDate date] retain];
//You code here...
double deltaTime = [[NSDate date] timeIntervalSinceDate:tmpStartData];
NSLog(@">>>>>>>>>>cost time = %f ms", deltaTime*1000);
CFTimeInterval begin = CFAbsoluteTimeGetCurrent();
for (int i = 0; i< 10000; i++) {
[[JMStudent alloc ]initWithDict:dict];
}
CFTimeInterval end = CFAbsoluteTimeGetCurrent();
NSLog(@"%f", end - begin);
3.UILabel显示html文本
NSString * htmlString = @"<html><body> Some html string \n <font size=\"13\" color=\"red\">This is some text!</font> </body></html>";
NSAttributedString * attrStr = [[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
UILabel * myLabel = [[UILabel alloc] initWithFrame:self.view.bounds];
myLabel.attributedText = attrStr;
[self.view addSubview:myLabel];
4.改变导航栏按钮的位置
leftItem = [[UIBarButtonItem alloc] initWithCustomView:leftButton];
UIBarButtonItem *space = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
space.width = -11;//自己设定
[self.navigationItem setLeftBarButtonItems:[NSArray arrayWithObjects:space,leftItem, nil]];
5.实现文字和边框之间有间隔 的一种方式
@interface TestUILabel : UILabel
@end
@implementation TestUILabel
- (void)drawTextInRect:(CGRect)rect {
//文字距离上下左右边框都有10单位的间隔
CGRect newRect = CGRectMake(rect.origin.x + 10, rect.origin.y + 10, rect.size.width - 20, rect.size.height -20);
[super drawTextInRect:newRect];
}
@end
6.去掉uitableviewcell的点击效果
在cell的初始化方法里设置
self.selectionStyle = UITableViewCellSelectionStyleNone;
7.tableView滚动到最下边的方法
//方法一:
[self.tableV setContentOffset:CGPointMake(0, self.tableV.contentSize.height -self.tableV.bounds.size.height<0?0:self.tableV.contentSize.height -self.tableV.bounds.size.height+10) animated:YES];
//方法二:
[self.tableV scrollToRowAtIndexPath:[NSIndexPath indexPathForItem:self.dataSource.count -1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:NO];
8.去除 No Results 标签,需要设置 UISearchDisplayController的delegate
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
//去除 No Results 标签
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.001);
dispatch_after(popTime, dispatch_get_main_queue(), ^{
for (UIView *subview insearchDisplayController.searchResultsTableView.subviews) {
if ([subview isKindOfClass:[UILabel class]] && [[(UILabel *)subview text] isEqualToString:@"No Results"]) {
UILabel *label = (UILabel *)subview;
label.text = @"无结果";
break;
}
}
});
return YES;
}
9.子视图的层次关系控制
//方式一:
[self.view insertSubview:buyView aboveSubview:self.scrollView];
[self.view insertSubview:Son1View atIndex:0]
[self.view insertSubview:son2View belowSubview:son3View];
//方式二:
[self.view bringSubviewToFront:buyBtn];//使得buyBtn位于最上层
[self.view sendSubviewToBack:buyView];//使得buyBtn位于下层
10. iOS开发中方法延迟执行的几种方式
- performSelector方法
这个方法必须要在主线程中使用.可以传递参数.可以取消操作,不能暂停. - NSTimer定时器
特点:这个方法必须要在主线程中使用.可以传递参数.可以取消操作,可以暂停,可以立即执行延迟操作,尊却度受runloop 的影响 - NSThread线程的sleep--
特点:卡主当前线程来实现延迟操作,使用需谨慎. 有些时候,用起来还是很方便的. - GCD
特点:这个方法不限制线程,不容易取消操作.
注意:NSThread是一种阻塞执行方式,其它都是非阻塞执行方式。
实例:
import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) NSTimer timer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLog(@"delayMethodStart");
[self methodOnePerformSelector];
// [self methodTwoNSTimer];
// [self methodThreeSleep];
// [self methodFourGCD];
NSLog(@"nextMethod");
}
- (void)methodFiveAnimation
{
[UIView animateWithDuration:0 delay:2.0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
} completion:^(BOOL finished) {
[self delayMethod];
}];
}
- (void)methodFourGCD
{
__block ViewController weakSelf = self;
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC));
dispatch_after(delayTime, dispatch_get_main_queue(), ^{
[weakSelf delayMethod];
});
}
- (void)methodThreeSleep
{
[NSThread sleepForTimeInterval:2.0];
}
- (void)methodTwoNSTimer
{
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(delayMethod) userInfo:nil repeats:NO];
}
- (void)methodOnePerformSelector
{
[self performSelector:@selector(delayMethod) withObject:nil/*可传任意类型参数*/ afterDelay:2.0];
}
- (void)delayMethod
{
NSLog(@"delayMethodEnd");
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
11.从导航堆栈中删除viewcontrollers
NSMutableArray *navigationArray = [[NSMutableArray alloc] initWithArray: self.navigationController.viewControllers];
// [navigationArray removeAllObjects];
[navigationArray removeObjectAtIndex: 2];
self.navigationController.viewControllers = navigationArray;
12.自定义对象的神拷贝
//自定义深拷贝,实现copyWithZone方法
-(id)copyWithZone:(NSZone *)zone{
car *newCard = [[[self class] allocWithZone:zone] init];
newCard.name = self.name;
newCard.age = self.age;
return newCard;
}
13.IOS-- UIView中的坐标转换
// 将像素point由point所在视图转换到目标视图view中,返回在目标视图view中的像素值
- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view;
// 将像素point从view中转换到当前视图中,返回在当前视图中的像素值
- (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view;
// 将rect由rect所在视图转换到目标视图view中,返回在目标视图view中的rect
- (CGRect)convertRect:(CGRect)rect toView:(UIView *)view;
// 将rect从view中转换到当前视图中,返回在当前视图中的rect
- (CGRect)convertRect:(CGRect)rect fromView:(UIView *)view;
例: 把UITableViewCell中的subview(btn)的frame转换到 controllerA中
// controllerA 中有一个UITableView, UITableView里有多行UITableVieCell,cell上放有一个button
// 在controllerA中实现:
CGRect rc = [cell convertRect:cell.btn.frame toView:self.view];
或
CGRect rc = [self.view convertRect:cell.btn.frame fromView:cell];
// 此rc为btn在controllerA中的rect
或当已知btn时:
CGRect rc = [btn.superview convertRect:btn.frame toView:self.view];
或
CGRect rc = [self.view convertRect:btn.frame fromView:btn.superview];
14.UITextView 取消换行 文字自动向右滚动
inputView_.textContainer.maximumNumberOfLines = 1;
inputView_.textContainer.lineBreakMode = NSLineBreakByTruncatingHead;
15.iOS App 唤醒另一个App
http://www.jianshu.com/p/7a308f5b89fc
4.当然这时候你可能才想到,那不是很多应用程序都会被其他垃圾程序调用了,查找资料过后,原来还有后续
我们重载这个方法
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
if ([sourceApplication isEqualToString:@"AC.achao.com"])
{
NSLog(@"%@", sourceApplication); //来源于哪个app(Bundle identifier)
NSLog(@"scheme:%@", [url scheme]); //url scheme
NSLog(@"query: %@", [url query]); //查询串 用“?...”格式访问
return YES;
}
else
return NO;
}
这就满足我们的需求了,我们可以通过sourceApplication来判断来自哪个app以决定要不要唤醒自己的app,也可以通过[url query]来获得查询串,这个时候我们需要更改app2的访问方式才能获得这个参数
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"achao://hello?name=achao-AC"]];//url不能有空格
我们也可以直接在safari离输入"achao://hello?name=achao-AC"来访问我们的app1,这个时候sourceApplication就是@"com.apple.mobilesafari"
总结:类似下面的方法
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.baidu.com"]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms://158********"]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://158********"]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"mailto://362****@qq.com"]];
我们用过很多,估计也是程序内部设置了类似的url scheme来供其他应用程序操作的
16.Objective-C学习——中文URL编码和解码
发现NSString类中有内置的方法可以实现。他们分别是:
- (NSString *)stringByAddingPercentEscapesUsingEncoding:(NSStringEncoding)encoding
- (NSString *)stringByReplacingPercentEscapesUsingEncoding:(NSStringEncoding)encoding
只要传入相应的编码即可以进行编码和解码了,不过此方法是对整个Url进行编码的所以如果有Query String中带有&?/等是不会进行编码转换的
NSString* string1 = @"https://www.cloudsafe.com/文件夹";
NSString* string2 = [string1 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString* string4 = [string2 stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
//string1:https://www.cloudsafe.com/文件夹
//string2:https://www.cloudsafe.com/%E6%96%87%E4%BB%B6%E5%A4%B9
//string3:https://www.cloudsafe.com/%25E6%2596%2587%25E4%25BB%25B6%25E5%25A4%25B9
//string4:https://www.cloudsafe.com/文件夹
17.dismissViewController跳转到RootViewController、跳转到指定ViewController
如何跳转到根视图控制器
UIViewController * presentingViewController = self.presentingViewController;
while (presentingViewController.presentingViewController) {
presentingViewController = presentingViewController.presentingViewController;
}
[presentingViewController dismissViewControllerAnimated:YES completion:nil];
上面代码中的while的作用就是通过循环找出根视图控制器的所在
如何跳转到指定视图控制器:
跳转到指定的视图控制器是根据视图控制器的类名进行判断,在栈中找到相对应得视图控制器进行跳转
UIViewController * presentingViewController = self.presentingViewController;
do {
if ([presentingViewController isKindOfClass:[类名 class]]) {
break;
}
presentingViewController = presentingViewController.presentingViewController;
} while (presentingViewController.presentingViewController);
[presentingViewController dismissViewControllerAnimated:YES completion:nil];
18.objcet-c中block的使用
//本地变量:
returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...};
//属性:
@property (nonatomic, copy, nullability) returnType (^blockName)(parameterTypes);
//方法参数:
- (void)someMethodThatTakesABlock:(returnType (^nullability)(parameterTypes))blockName;
//作为一个方法里的参数:
[someObject someMethodThatTakesABlock:^returnType (parameters) {...}];
//宏定义:
typedef returnType (^TypeName)(parameterTypes);
TypeName blockName = ^returnType(parameters) {...};
19.ios UITableViewCell 左滑删除时,改变删除按钮背景颜色
-(NSArray<UITableViewRowAction*>*)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewRowAction *rowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"删除" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
// 点击删除时 do something
}];
// rowActionSec.backgroundColor = [UIColor colorWithHexString:@"f38202"];
rowAction.backgroundColor = [UIColor purpleColor];
UITableViewRowAction *rowaction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"置顶" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
// 点击置顶时 do something
}];
rowaction.backgroundColor = [UIColor grayColor];
NSArray *arr = @[rowAction,rowaction];
return arr;
}
20.状态栏的隐藏
在控制器设置状态栏隐藏
- (BOOL)prefersStatusBarHidden
{
return TRUE;
}
在info.plist文件中 View controller-based status bar appearance
-> YES,则控制器对状态栏设置的优先级高于application
-> NO,则以application为准,控制器设置状态栏prefersStatusBarHidden是无效的的根本不会被调用
21.打开模拟器沙盒路径:
断点到某个页面的viewdidload里,然后打印:NSHomeDirectory()
22.照片保存到相册的三种方法
23.设置 UITableview 的间隔线
self.tableV.separatorColor = ARGB(0xffe4e4e4);
self.tableV.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsMake(0, 0, 0, 0)];
}
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
if([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
[cell setPreservesSuperviewLayoutMargins:NO];
}
}
24.自动布局的动态高度计算
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NewsListTableCell *cell;
//只初始化一次cell
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
cell = [tableView dequeueReusableCellWithIdentifier:NewsListTableCellId];
});
newsModel *model = self.dataSource[indexPath.row];
cell.model = model;
if (model.cellHeight <= 0) {
//使用systemLayoutSizeFittingSize获取高度
model.cellHeight = [cell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height + 1;
}
return model.cellHeight;
}
25.restful网络请求框架封装
/**
restful请求方式
@param method GET POST PUT DELETE
@param url url
@param paramDic paramDic
@param responses
*/
+ (void)sendResultToServiceWithMethod:(NSString *)method WithUrl:(NSString *)url param:(NSDictionary *)paramDic header:(NSDictionary *)headerDic success:(successBlock)success failure:(failureBlock)failure
{
NSURLSession *session = [NSURLSession sharedSession];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:method];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
NSDictionary *header = [self getHeader];
[header enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
[request setValue:obj forHTTPHeaderField:key];
}];
[headerDic enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
[request setValue:obj forHTTPHeaderField:key];
}];
if (paramDic) {
request.HTTPBody = [NSJSONSerialization dataWithJSONObject:paramDic options:NSJSONWritingPrettyPrinted error:nil];
}
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// NSHTTPURLResponse *realResponse = (NSHTTPURLResponse *)response;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSString *errnoCode = [NSString stringWithFormat:@"%@", dict[@"errno"]];
dispatch_async(dispatch_get_main_queue(), ^{
if ([[dict[@"errno"] stringValue] isEqualToString:@"0"]) {
success(dict, errnoCode);
}
else
{
if (failure) {
failure([NSError errorWithDomain:@"" code:[errnoCode integerValue] userInfo:nil]);
}
}
});
}];
[task resume];
}
26.UILabel 根据文本获取其 size
1. sizeThatFits
CGSize size = [self.priceLabel sizeThatFits:CGSizeMake(CGFLOAT_MAX,17*SCALE)];
[self.priceLineView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(@(0.5));
make.centerY.mas_equalTo(self.priceLabel.mas_centerY).offset(0);
make.trailing.equalTo(self.mas_trailing).with.offset(-30*SCALE);
make.width.mas_equalTo(size.width+5);
}];
2. boundingRectWithSize
NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
paragraph.lineBreakMode = NSLineBreakByWordWrapping;
paragraph.lineSpacing = lineSpacing;
paragraph.paragraphSpacing = paragraphSpacing;
CGSize size = [self boundingRectWithSize:paddingSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName : font,
NSParagraphStyleAttributeName : paragraph}
context:nil].size;
27.ios防止按钮重复点击事件
方法一:
1.宏定义:
// 防止多次调用
define kPreventRepeatClickTime(seconds) \
static BOOL shouldPrevent;
if (shouldPrevent) return;
shouldPrevent = YES;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)((seconds) * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
shouldPrevent = NO;
});
2.在所需要的button或者cell的action前调用即可:
kPreventRepeatClickTime(0.5);
28.uitableview 设置 sectionHeader 不停留
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat sectionHeaderHeight = iPhone5?40: 52;
if (scrollView.contentOffset.y<=sectionHeaderHeight&&scrollView.contentOffset.y>=0) {
scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
} else if (scrollView.contentOffset.y>=sectionHeaderHeight) {
scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0);
}
}
29.使用Runtime完成归档与解档
//.h文件,与上面定义相同
#import <Foundation/Foundation.h>
@interface Person : NSObject<NSCoding>
@property(nonatomic,strong) NSString * name;
@property(nonatomic,strong) NSString * gender;
@property(nonatomic,strong) NSString * address;
@property(nonatomic) NSUInteger age;
-(instancetype)initWithName:(NSString*)name gender:(NSString*)gender address:(NSString*)adderss age:(NSUInteger)age;
@end
.m文件
#import "Person.h"
#import <objc/runtime.h>
@implementation Person
/*
使用runtime进行解档与归档。
*/
-(void)encodeWithCoder:(NSCoder *)aCoder{
unsigned int count = 0;
Ivar *ivarLists = class_copyIvarList([Person class], &count);// 注意下面分析
for (int i = 0; i < count; i++) {
const char* name = ivar_getName(ivarLists[i]);
NSString* strName = [NSString stringWithUTF8String:name];
[aCoder encodeObject:[self valueForKey:strName] forKey:strName];
}
free(ivarLists); //一定不要忘了,自己释放。
}
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
unsigned int count = 0;
Ivar *ivarLists = class_copyIvarList([Person class], &count);
for (int i = 0; i < count; i++) {
const char* name = ivar_getName(ivarLists[i]);
NSString* strName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
id value = [aDecoder decodeObjectForKey:strName];
[self setValue:value forKey:strName];
}
free(ivarLists);
}
return self;
}
-(instancetype)initWithName:(NSString *)name gender:(NSString *)gender address:(NSString *)adderss age:(NSUInteger)age{
if (self = [super init]) {
_name = name;
_gender = gender;
_address = adderss;
_age = age;
}
return self;
}
-(NSString*)description{
return [NSString stringWithFormat:@"name:%@ gender:%@ age:%lu address:%@",self.name,self.gender,(unsigned long)self.age,self.address];
}
@end
30.点击提示框视图以外的其他地方时隐藏弹框
// 点击提示框视图以外的其他地方时隐藏弹框
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
CGPoint point = [[touches anyObject] locationInView:self];
point = [self.alertView.layer convertPoint:point fromLayer:self.layer];
if (![self.alertView.layer containsPoint:point]) {
self.hidden = YES;
}
}
网友评论