iOS小问题备忘

iOS-MEMO

随记:遇到的iOS小问题及解决办法

貌似csdn的markdown语法和GitHub不大一样。目录跳转怪怪的。
GitHub链接:ios-MEMO

目录

AFN在路径里含有中文或空格时的错误及解决

Assertion failure in -[AFHTTPRequestSerializer requestWithMethod:URLString:parameters:error:]

path = [path stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

AFN超时设置

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer.timeoutInterval = 300;

导航控制器pop到指定页面

NSInteger index = 1;
UIViewController *destVC = self.navigationController.viewControllers[index];
[self.navigationController popToViewController:destVC animated:YES];

关于iOS地图定位中点击设置中定位服务闪退问题

iOS8之后,如果应用中用到了地图定位,那么点击设置->隐私->定位服务 再点击该应用有时候会出现闪退问题,其原因是iOS8之后定位中添加了
NSLocationWhenInUseDescriptionNSLocationAlwaysUsageDescription,需要在plist文件中添加这两个或其中一个,出现闪退是因为在plist中把这两个值设成了Boolean类型的,将其改成NSString就不会闪退了.

加入购物车红点贝塞尔曲线动画效果

 UIImageView * action = (UIImageView *)[cell.contentView viewWithTag:10];

    CALayer *transitionLayer = [[CALayer alloc] init];

    [CATransaction begin];

    [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];

    transitionLayer.opacity = 1.0;

    transitionLayer.contents = action.layer.contents;

    transitionLayer.frame = [self.view convertRect:action.bounds fromView:action];

    [self.view.layer addSublayer:transitionLayer];

    [CATransaction commit];   

    //路径曲线

    UIBezierPath *movePath = [UIBezierPath bezierPath];

    [movePath moveToPoint:transitionLayer.position];//起点

    CGPoint toPoint = CGPointMake(30, 568-64-30); //终点

    [movePath addQuadCurveToPoint:toPoint  controlPoint:CGPointMake(26,transitionLayer.position.y-120)]; 

    //关键帧

    CAKeyframeAnimation *positionAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];

    positionAnimation.path = movePath.CGPath;

    positionAnimation.removedOnCompletion = YES;

    CAAnimationGroup *group = [CAAnimationGroup animation];

    group.beginTime = CACurrentMediaTime();

    group.duration = 0.7;

    group.animations = [NSArray arrayWithObjects:positionAnimation,nil];

    group.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

    group.delegate = self;

    group.fillMode = kCAFillModeForwards;

    group.removedOnCompletion = NO;

    group.autoreverses= NO;

    [transitionLayer addAnimation:group forKey:@"opacity"];

取得当前设备启动图的确切名称

//取得当前设备启动图的确切名称

- (NSString *)launchImageName {

    NSString *name = nil;

    CGSize windowSize = [UIScreen mainScreen].bounds.size;    
    NSArray* images = [[NSBundle mainBundle] infoDictionary][@"UILaunchImages"];
    for (NSDictionary* info in images) {
        CGSize imageSize = CGSizeFromString(info[@"UILaunchImageSize"]);
        if ( CGSizeEqualToSize(imageSize, windowSize) ) {
            name = info[@"UILaunchImageName"];
            break;
        }
    }

    if (name == nil) {
        name = @"LetGo";
    }

    return name;
}

取消tableviewheader悬停

改tableviewStlye为group类型,当然之后调整下显示。

如果父视图半透明,如何使子视图不随着半透明

不用alpha,改用透明色即可
superView.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.5];

状态栏里的ActivityIndicator

[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

cell的动态进入效果

在tableview的- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath这个代理里面实现:
static CGFloat initialDelay = 0.2f;
static CGFloat stutter = 0.06f;
cell.contentView.transform =  CGAffineTransformMakeTranslation(kFBaseWidth, 0);
[UIView animateWithDuration:1. delay:initialDelay + ((indexPath.row) * stutter) usingSpringWithDamping:0.6 initialSpringVelocity:0 options:0 animations:^{
                cell.contentView.transform = CGAffineTransformIdentity;
            } completion:NULL];

Emoji表情上传与下载后显示转换

为了避免服务器奔溃,上传时转成Unicode编码
NSData *data = [emojiString dataUsingEncoding:NSNonLossyASCIIStringEncoding];
NSString *valueUnicode = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

从服务器获取后逆向来一遍
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
NSString *valueEmoj = [[NSString alloc] initWithData:data encoding:NSNonLossyASCIIStringEncoding];

以上方式在iOS手机间可以正常运作,但是无法和安卓统一~(处理机制不一样)——可以用GitHub上的一个库NSStringEmojize,表情不全,勉强可用.

iOS系统功能调用

1、调用 电话phone

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://4008008288"]];


2、调用自带 浏览器 safari

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.abt.com"]];


3、调用 自带mail

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"mailto://admin@abt.com"]];


4、调用 SMS

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms://800888"]];


5,跳转到系统设置相关界面

1 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=WIFI"]];
其中,发短信,发Email的功能只能填写要发送的地址或号码,无法初始化发送内容,如果想实现内容的话,还需要更复杂一些,实现其各自的委托方法。

若需要传递内容可以做如下操作:

 1 //加入:MessageUI.framework
 2  #import <MessageUI/MFMessageComposeViewController.h>
 3  
 4 //实现代理:MFMessageComposeViewControllerDelegate
 5 
 6  //调用sendSMS函数  
 7 //内容,收件人列表  
 8 - (void)sendSMS:(NSString *)bodyOfMessage recipientList:(NSArray *)recipients  
 9 {   
11     MFMessageComposeViewController *controller = [[[MFMessageComposeViewController alloc] init] autorelease];   
13     if([MFMessageComposeViewController canSendText])   
15     {   
17         controller.body = bodyOfMessage;    
19         controller.recipients = recipients;   
21         controller.messageComposeDelegate = self;   
23         [self presentModalViewController:controller animated:YES];  
25     }      
27 }  
28    
29 // 处理发送完的响应结果  
30 - (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result  
31 {  
32   [self dismissModalViewControllerAnimated:YES];   
34   if (result == MessageComposeResultCancelled)  
35     NSLog(@"Message cancelled")  
36   else if (result == MessageComposeResultSent)  
37     NSLog(@"Message sent")    
38   else   
39     NSLog(@"Message failed")    
40 }  
发送邮件的为:  

 1 //导入MFMailComposeViewController
 2 #import <MessageUI/MFMailComposeViewController.h>  
 3 //实现代理:MFMailComposeViewControllerDelegate  
 4    
 5 //发送邮件  
 6 -(void)sendMail:(NSString *)subject content:(NSString *)content{  
 7   MFMailComposeViewController *controller = [[[MFMailComposeViewController alloc] init] autorelease];  
 9     if([MFMailComposeViewController canSendMail])   
11     {   
13         [controller setSubject:subject];    
15         [controller setMessageBody:content isHTML:NO];    
17         controller.mailComposeDelegate = self;   
19         [self presentModalViewController:controller animated:YES];   
21     }      
22 }  
23    
24 //邮件完成处理  
25 -(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error{  
27     [self dismissModalViewControllerAnimated:YES];   
29     if (result == MessageComposeResultCancelled)  
30         NSLog(@"Message cancelled");  
31     else if (result == MessageComposeResultSent)  
32         NSLog(@"Message sent");   
33     else   
34         NSLog(@"Message failed");    
35    
36 }  
37    
默认发送短信的界面为英文的,解决办法为:在.xib 中的Localization添加一組chinese   

NSDictinary,NSArray,JSonString,NSData转换

//字典、数组、JSonString - NSData

int main(int argc, const char * argv[]) {
    @autoreleasepool {

        NSDictionary *dic = @{@"key1":@"v1", @"key2":@"v2"};
        //options:NSJSONWritingPrettyPrinted,若改为0则下边的dicString是紧凑的不带空格和换行的形式
        NSData *data = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil];
        //options:若为0则dictionary为不可变版本
        NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"data - dictionary =%@",dictionary);
        NSString *dicString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"dic String:  %@", dicString);

        NSArray *array = @[@11, @33, @59];
        //options:0,若改为NSJSONWritingPrettyPrinted则会加上回车和空格以适应漂亮打印
        NSData *arrData = [NSJSONSerialization dataWithJSONObject:array options:0 error:nil];
        NSArray *finalArray = [NSJSONSerialization JSONObjectWithData:arrData options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"data - array : %@", finalArray);
        NSString *arrString = [[NSString alloc] initWithData:arrData encoding:NSUTF8StringEncoding];
        NSLog(@"arr String:  %@", arrString);

    }
    return 0;
}

scrollView(tableView)上下滑动渐变显示导航栏

//scrollView(tableView)上下滑动渐变显示导航栏

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat offsetY = scrollView.contentOffset.y;

        CGFloat criticalHeight = 75

        UIColor * naveColor =...;

        CGFloat alpha = offsetY / criticalHeight));

        self.navBar.backgroundColor = [naveColor colorWithAlphaComponent:alpha];

}

webView缓存策略

NSString *stringUrl = …;
NSURL *url = [NSURL URLWithString:stringUrl];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:15];
[webView loadRequest:request];

WebView疑难杂症两则

1.自适应内容高度

//设置内容,这里包装一层div,用来获取内容实际高度(像素),htmlcontent是html格式的字符串  
  NSString * htmlcontent = [NSString stringWithFormat:@"<div id=\"webview_content_wrapper\">%@</div>", htmlcontent];
  [_webView loadHTMLString:htmlcontent baseURL:nil];

//delegate的方法重载//
- (void)webViewDidFinishLoad:(UIWebView *)webView {
  //获取页面高度(像素)
  NSString * clientheight_str = [webView stringByEvaluatingJavaScriptFromString: @"document.body.offsetHeight"];
  float clientheight = [clientheight_str floatValue];
  //设置到WebView上
  webView.frame = CGRectMake(0, 0, self.view.frame.size.width, clientheight);
  //获取WebView最佳尺寸(点)
  CGSize frame = [webView sizeThatFits:webView.frame.size];
  //获取内容实际高度(像素)
  NSString * height_str= [webView stringByEvaluatingJavaScriptFromString: @"document.getElementById('webview_content_wrapper').offsetHeight + parseInt(window.getComputedStyle(document.getElementsByTagName('body')[0]).getPropertyValue('margin-top'))  + parseInt(window.getComputedStyle(document.getElementsByTagName('body')[0]).getPropertyValue('margin-bottom'))"];
  float height = [height_str floatValue];
  //内容实际高度(像素)* 点和像素的比
  height = height * frame.height / clientheight;
  //再次设置WebView高度(点)
  webView.frame = 。。。
}

2.去除webview底部黑线~

    webView.opaque = NO;

    webView.backgroundColor = [UIColor whiteColor];

xib自定义view初始化

#import <UIKit/UIKit.h>

@interface SATourView : UIView

@property (strong, nonatomic) IBOutlet UIView *view;
@property (weak, nonatomic) IBOutlet UILabel *mainTitleLabel;
@property (weak, nonatomic) IBOutlet UIImageView *mainImage;

@end

#import "SATourView.h"

@implementation SATourView


- (instancetype)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];

    if (self) {

        // 1. Load .xib

        // 2. Adjust bounds

        // 3. Add as a subview

        [[NSBundle mainBundle] loadNibNamed:@"SATourView" owner:self options:nil];

        NSLog(@"frame = %@", NSStringFromCGRect(self.view.bounds));
        NSLog(@"bounds = %@", NSStringFromCGRect(self.bounds));

        self.bounds = self.view.bounds;

        [self addSubview:self.view];
    }
    return self;
}


- (id)initWithCoder:(NSCoder *)aDecoder {

    self = [super initWithCoder:aDecoder];

    if (self) {
        [[NSBundle mainBundle] loadNibNamed:@"SATourView" owner:self options:nil];

        [self addSubview:self.view];
    }

    return self;
}

- (IBAction)joinButtonTapped:(id)sender {

    NSLog(@"joinButtonTapped");
}


@end

SATourView *view1 = [[SATourView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
    view1.bounds = self.view.bounds;
    view1.mainTitleLabel.text = @"Новый текст";

    [self.view addSubview:view1];


xib自定义view2初始化+IBInspectable
#import <UIKit/UIKit.h>
@interface DraggableView : UIView

@property (nonatomic, assign) IBInspectable NSInteger cornerRadius;

@end

#import "DraggableView.h"

@interface DraggableView ()

@property (weak, nonatomic) IBOutlet UILabel *leftLabel;
@property (weak, nonatomic) IBOutlet UILabel *rightLabel;

@end

@implementation DraggableView

- (instancetype)initWithCoder:(NSCoder *)aDecoder {

    if (self = [super initWithCoder:aDecoder]) {

        [self load];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {

    if (self = [super initWithFrame:frame]) {

        [self load];
    }
    return self;
}

- (void)load {
    UIView *view = [[[NSBundle bundleForClass:[self class]] loadNibNamed:@"DraggableView" owner:self options:nil] firstObject];
    view.frame = self.bounds;

    [self addSubview:view];

    self.leftLabel.text = @"works";
    self.rightLabel.text = @"done :)";
}

- (void)setCornerRadius:(NSInteger)cornerRadius
{
    self.layer.cornerRadius = cornerRadius;
    self.clipsToBounds = YES;
}

@end


#import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *draggableViewHeightConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *draggableViewWidthConstraint;
@end

@implementation ViewController
#pragma mark - View lifecycle

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (void)viewDidLoad {
    [super viewDidLoad];

    self.draggableViewHeightConstraint.constant
    = 200;
    self.draggableViewWidthConstraint.constant = 200;
}
@end

IB里添加手势奔溃

在xib或者storyBoard里添加单击手势识别者导致奔溃,目前是自定义tableViewCell遇到
解决:
用代码添加手势识别者。

点击webView跳转到safari

某个页面里嵌入了webview,本来只是用来展示静态html内容,但有一天市场部的需要里边有链接。点击链接后去那里?安卓会用本地浏览器打开,所以产品经理说iOS也该用safari打开。
奇葩需求,不过实现倒是不难。在代理方法里拦截url即可。

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    // 若用户点击了链接,用safari打开
    NSString *url = request.URL.absoluteString;
    if ([url isEqualToString:@"about:blank"]) { return YES; }
    [[UIApplication sharedApplication]openURL:[NSURL URLWithString:url]];
    return NO;
}
注意,一开始就是加载的静态html文本,所以url是"about:blank",这个放行,让这些内容加载显示。
当用户点击了某个链接后,会再次来到这个方法,拦截url,跳转到safari打开即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值