ios工作中的一些筆記 - (持續不定期更新)2018.01.15

//1. 時間戳格式化
- (NSString *)timeFormatWithTimeStamp:(NSString *)aStamp
{
      NSDate *d = [[NSDate alloc]initWithTimeIntervalSince1970:[aStamp longLongValue]/1000] ;
      NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
      dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
      return [dateFormatter stringFromDate:d];
}

// 快速獲取當前本機 yyyy-MM-dd格式的時間字符串
    NSDateFormatter* dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"yyyy-MM-dd"];
    NSString *dateString = [dateFormat stringFromDate:[NSDate date]];
// 獲取昨天的日期
    NSDate *yesterday = [NSDate dateWithTimeIntervalSinceNow:-(24*60*60)];
2. Xcode升級后插件失效的原理與修復辦法
打開terminal輸入以下命令 : 
    find ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins -name Info.plist -maxdepth 3 | xargs -I{} defaults write {} DVTPlugInCompatibilityUUIDs -array-add `defaults read /Applications/Xcode.app/Contents/Info.plist DVTPlugInCompatibilityUUID`
然后退出Xcode 重新打開  點loadBundleXX 然后就恢復了
3.設置導航欄透明, translute 勾選, 設置一張透明背景圖**
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"nav_bargound.png"] forBarMetrics:UIBarMetricsCompact];

 [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault]; self.navigationController.navigationBar.shadowImage = [[UIImage alloc] init];
4.使用iOS接收服務器傳來的數據時,出現"<null>",嘗試使用isEqual:和@“”,NULL, @"(null)" ,nil,Nil比較后均得不到正確結果,最后的解決辦法是
    if([m_result isEqual:[NSNUll null]]){ 
          NSLog(@"KDA!");
    }
5.取消tableView分割線左邊的15像素
  在代理方法中進行如下設置:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
        [cell setSeparatorInset:UIEdgeInsetsZero];
    }
    
    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}
并且 在ViewDidLoad里面調用下面方法即可  此種去間距操作僅適用與iOS8 以上 iOS7 只需設置setSeparatorInset:UIEdgeInsetsZero 就能將空白去掉

-(void)cancelMarginsForTableView
{
    if ([self.menageTable respondsToSelector:@selector(setSeparatorInset:)]) {
        [self.menageTable setSeparatorInset:UIEdgeInsetsZero];
    }
    if ([self.menageTable respondsToSelector:@selector(setLayoutMargins:)]) {
        [self.menageTable setLayoutMargins:UIEdgeInsetsZero];
    }
}
6. K線圖組件,都是比較不錯的??梢詫W習下 具體使用還要修改:
https://github.com/danielgindi/ios-charts 
https://github.com/SoftProgramLX/LXKLine
https://github.com/chenyk0317/YKLineChartView
https://github.com/yate1996/YYStock  // 比較給力,和螞蟻聚寶效果一樣。
https://github.com/yate1996/Y_KLine // 另一種,同一人所寫
https://github.com/HeterPu/PHStockChart
https://github.com/HeterPu/PHStockChartForSwift
LXKLine

YKLineChartView

Y_KLine

YYStock
7.  CGRect rect  = [str boundingRectWithSize:CGSizeMake(100, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:20.0]} context:nil];  
    新api計算高度不準確時,請注意參數問題
    options,attributes
    其中,options 參數請使用:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
    設置兩個枚舉,不要設置一個。

8. iOS 開發學習路線 鏈接地址

look
9. iOS關于友盟統計錯誤分析 dSYM文件分析工具 解析崩潰日志 友盟統計報表解讀以及錯誤分析

10.   案例:  比較文章/帖子類似的發布時間  (代碼片段貌似有點略不好,有更好的寫法或者比較方法,大神們可以指導下)
- (NSString *)newsTime:(NSString *)newsTimes
{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.dateFormat = knewsTimeFormat;
    formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:kLocaleIdentifier];
    NSDate *date = [formatter dateFromString:newsTimes];
    NSDate *now = [NSDate date];

    // 比較 文章/帖子/或者用戶發布內容的發布時間和當前時間
    NSTimeInterval interval = [now timeIntervalSinceDate:date];
    NSString *format;
    if (interval <= 60) {
        format = @"剛剛";
    } else if(interval <= 60*60){
        format = [NSString stringWithFormat:@"發布于前%.f分鐘", interval/60];
    } else if(interval <= 60*60*24){
        format = [NSString stringWithFormat:@"發布于前%.f小時", interval/3600];
    } else if (interval <= 60*60*24*7){
        format = [NSString stringWithFormat:@"發布于前%d天", (int)interval/(60*60*24)];
    } else if (interval > 60*60*24*7 & interval <= 60*60*24*30 ){
        format = [NSString stringWithFormat:@"發布于前%d周", (int)interval/(60*60*24*7)];
    }else if(interval > 60*60*24*30 ){
        format = [NSString stringWithFormat:@"發布于前%d月", (int)interval/(60*60*24*30)];
    }
    formatter.dateFormat = format;
    return [formatter stringFromDate:date];
}

11.  iOS 圖片拉伸解決辦法
     UIImage *image = [UIImage imageNamed:@"test.png"];
     image = [image   stretchableImageWithLeftCapWidth:floorf(image.size.width/2)topCapHeight:floorf(image.size.height/2)];
12. 調用系統API
//撥打電話
- (IBAction)onClickCallPhone:(id)sender {    
     NSString *url = [NSString stringWithFormat:@"telprompt://%@",self.phoneNumField.text];   
     [self openUrl:url];
}
// 發送短信
- (IBAction)onClickSendMsg:(id)sender {  
      NSString *url = [NSString stringWithFormat:@"sms://%@",self.phoneNumField.text];   
     [self openUrl:url];
}
// 發送郵件
- (IBAction)onClickEmail:(id)sender {    
    NSString *url = [NSString stringWithFormat:@"mailto://%@",self.phoneNumField.text];   
   [self openUrl:url];
}
// 瀏覽網頁
- (IBAction)onClickBrowser:(id)sender {  
        NSString *url = @"http://www.baidu.com";   
        [self openUrl:url];
}

-(void)openUrl:(NSString *)urlStr{  
       //注意url中包含協議名稱,iOS根據協議確定調用哪個應用,例如發送郵件是“sms://”其中“//”可以省略寫成“sms:”(其他協議也是如此)    
      NSURL *url = [NSURL URLWithString:urlStr];    
      UIApplication *application = [UIApplication sharedApplication];    
      if (![application canOpenURL:url]) {        
              UIAlertView *alert = [[UIAlertView alloc]initWithTitle:nil message:@"無法打開" delegate:self cancelButtonTitle:@"返回" otherButtonTitles:nil];       
              [alert show];     
             return;    
          }    
      [[UIApplication sharedApplication]openURL:url];
}
  13. 調整UILabel的行間距
      NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];      
      NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]initWithString:_placeHolderLable.text];    

      [paragraphStyle setLineSpacing:20];//調整行間距   

      [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [_placeHolderLable.text length])];   
     _placeHolderLable.attributedText = attributedString;    
     [self.textView addSubview:_placeHolderLable];   
     [_placeHolderLable sizeToFit];
14. 圖片模糊處理  (注意:此方法需要導入 CoreImage的framework   #import <CoreImage/CoreImage.h>)
    // 圖片模糊化處理  邊緣模糊
- (UIImage*) blur:(UIImage*)theImage{  
     CIContext *context = [CIContext contextWithOptions:nil];    
    CIImage *inputImage = [CIImage imageWithCGImage:theImage.CGImage];    
    CIFilter *blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];    
    [blurFilter setValue:inputImage forKey:kCIInputImageKey];  
    [blurFilter setValue:[NSNumber numberWithFloat:10.0f] forKey:@"inputRadius"];    CIImage *result = [blurFilter valueForKey:kCIOutputImageKey];    CGImageRef cgImage = [context createCGImage:result fromRect:[inputImage extent]];    UIImage *returnImage = [UIImage imageWithCGImage:cgImage];    CGImageRelease(cgImage);
    return returnImage;
}
// 全部模糊
- (UIImage*) blur:(UIImage*)theImage
{   
      CIContext *context = [CIContext contextWithOptions:nil];   
       CIImage *inputImage = [CIImage imageWithCGImage:theImage.CGImage];    
       CIFilter *affineClampFilter = [CIFilter filterWithName:@"CIAffineClamp"]; 
       CGAffineTransform xform = CGAffineTransformMakeScale(1.0, 1.0);  
       [affineClampFilter setValue:inputImage forKey:kCIInputImageKey];   
       [affineClampFilter setValue:[NSValue valueWithBytes:&xform                                               objCType:@encode(CGAffineTransform)]                         forKey:@"inputTransform"];    
       CIImage *extendedImage = [affineClampFilter valueForKey:kCIOutputImageKey];    
       CIFilter *blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];   
       [blurFilter setValue:extendedImage forKey:kCIInputImageKey];   
       [blurFilter setValue:[NSNumber numberWithFloat:20.0] forKey:@"inputRadius"];   
       CIImage *result = [blurFilter valueForKey:kCIOutputImageKey];       
       CGImageRef cgImage = [context createCGImage:result fromRect:[inputImage extent]];  
       UIImage *returnImage = [UIImage imageWithCGImage:cgImage];  
       CGImageRelease(cgImage);  // 一定要釋放 凡是調用C語言的庫實例化的對象 到最后都需要手動進行釋放,否則會有內存問題  即便是ARC模式下
       return returnImage;
}
 15.   // 全屏截圖
- (UIImage *)imageFromView: (UIView *) theView
{
   UIGraphicsBeginImageContext(theView.frame.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [theView.layer renderInContext:context];
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
   return theImage;
}
16.  數字格式化,四舍五入
/**
  *  小數點格式化  四舍五入
  *
  *  @param format 保留幾位小數,格式 如三位小數 則傳入 0.000
  *  @param floatV 要格式化的數字
  *
  *  @return 格式化字符串
  */
- (NSString *) decimalwithFormat:(NSString *)format  floatV:(float)floatV  {
    NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
    [numberFormatter setPositiveFormat:format];
    return  [numberFormatter stringFromNumber:[NSNumber numberWithFloat:floatV]];
}

/**
 *  給文字添加下劃線
 *
 *  @param aString 要添加下劃線的字符串
 *
 *  @return 屬性字符串
 */
-(NSAttributedString *)addUnderLineForLabel:(NSString *)aString
{
    NSMutableAttributedString *content = [[NSMutableAttributedString alloc] initWithString:aString];
    NSRange contentRange = {0, [content length]};
    [content addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] range:contentRange];
    [content
     addAttribute:NSUnderlineColorAttributeName value:[UIColor blueColor] range:contentRange];
    return content;
}
// 搜索高亮顯示
- (NSMutableAttributedString *)colorData:(NSString *)dataString{
    NSMutableAttributedString *dataStr = [[NSMutableAttributedString alloc] initWithString:dataString];
    for (int i = 0; i < withStr.length - self.searchField.text.length+ 1; i++) {
        if ([[withStr substringWithRange:NSMakeRange(i, self.searchField.text.length)] isEqualToString:self.searchField.text]) {
            NSRange range = NSMakeRange(i, self.searchField.text.length);
            [dataStr addAttribute:NSForegroundColorAttributeName value:rgb(255, 114, 0) range:NSMakeRange(range.location,range.length)];
        }
    }
    return dataStr;
}
 // textField限制只允許輸入數字
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    return [self validateNumber:string];
}
 
- (BOOL)validateNumber:(NSString*)number {
    BOOL res = YES;
    NSCharacterSet* tmpSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
    int i = 0;
    while (i < number.length) {
        NSString * string = [number substringWithRange:NSMakeRange(i, 1)];
        NSRange range = [string rangeOfCharacterFromSet:tmpSet];
        if (range.length == 0) {
            res = NO;
            break;
        }
        i++;
    }
    return res;
} 

如果需要其他的需求,比如說 只能輸入英文 就把 @"0123456789" 這個字符串替換成英文字母 以此類推,還有另外一個方式:
#define NUMBERS @"0123456789"    //在頭部定義一個宏  基本思路就是截取字符串后查找對比,不符合就干掉。

- (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string
{
        NSCharacterSet*cs;
        cs = [[NSCharacterSetcharacterSetWithCharactersInString:NUMBERS] invertedSet];
        NSString*filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
        BOOLbasicTest = [string isEqualToString:filtered];
        if(!basicTest) {
             
            UIAlertView* alert = [[UIAlertViewalloc] initWithTitle:@"提示"
                                                            message:@"請輸入數字"
                                                           delegate:nil
                                                  cancelButtonTitle:@"確定"
                                                  otherButtonTitles:nil];
             
            [alert show];
            returnNO;
             
        }
    returnYES;
}


- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
   // 獲取 deviceToken
    NSString *deviceTokens = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    deviceTokens = [deviceTokens stringByReplacingOccurrencesOfString:@" " withString:@""];
  NSLO
}
項目運行,控制臺打印

[Project Name] was compiled with optimization - stepping may behave oddly; variables may not be available.
出現這個問題的原因是因為 你在調試的時候忘記切換會 debug模式了,在xcode
附解決鏈接: [http://stackoverflow.com/questions/32772573/project-name-was-compiled-with-optimization-stepping-may-behave-oddly-varia](http://stackoverflow.com/questions/32772573/project-name-was-compiled-with-optimization-stepping-may-behave-oddly-varia)
#pragma mark - 檢測appStore上的最新版本,與app當前版本作比較,如果不一樣,那就說明需要提醒用戶更新了。
#define  CheckVersionUrl  @"http://itunes.apple.com/lookup?id=your_appid"
-(void)checkUpAppVersion
{
    [NetworkManager getWithUrl:CheckVersionUrl params:nil success:^(id responseObject) {
        NSArray *array = responseObject[@"results"];
        NSDictionary *dict = [NSDictionary dictionaryWithDictionary:array[0]];
        DLog(@"%@",dict[@"version"]);
    } failure:^(NSError *error) {
    }];
}
// UIWebView圖片大小自適應解決方案
- (void)webViewDidFinishLoad:(UIWebView *)webView {
        NSString *js = @"function imgAutoFit() { \
        var imgs = document.getElementsByTagName('img'); \
        for (var i = 0; i < imgs.length; ++i) {\
                   var img = imgs[i]; \
                   img.style.maxWidth = %f; \
         } \
  }";

        js = [NSString stringWithFormat:js, [UIScreen mainScreen].bounds.size.width - 20];
        [webView stringByEvaluatingJavaScriptFromString:js];
        [webView stringByEvaluatingJavaScriptFromString:@"imgAutoFit()"];
}
安裝HomeBrew 錯誤
error: could not lock config file .git/config: Permission denied

解決辦法: 執行下面兩個命令
sudo chgrp -R admin /usr/local
sudo chmod -R g+w /usr/local
// Swift 2.x 版本的寫法
    /**
     是否自動轉換方向
     
     - returns:
     */
    override func shouldAutorotate() -> Bool {
        return false
    }
    /**
     支持的設備方向
     
     - returns:
     */
    override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return  [UIInterfaceOrientationMask.LandscapeRight]
    }
    
// Swift 3.0 +  更換成了屬性重寫
    
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return [UIInterfaceOrientationMask.portrait,UIInterfaceOrientationMask.landscapeLeft,UIInterfaceOrientationMask.landscapeRight]
}
    
override var shouldAutorotate: Bool {
    return false
}

// 可視化編輯 - Button. 其他的控件以此類推
@IBDesignable public class CircleButton: UIButton {

    @IBInspectable var borderColor:UIColor = UIColor.clearColor() {
        didSet{
            layer.borderColor = borderColor.CGColor
        }
    }
    
    @IBInspectable var borderWidth:CGFloat = 0 {
        didSet {
            layer.borderWidth = borderWidth
        }
    }
    
    @IBInspectable var cornerRadius:CGFloat = 0 {
        didSet {
            layer.cornerRadius = cornerRadius
            layer.masksToBounds = true
        }
    }
}
// 設置顏色擴展
public extension UIColor {
    
     convenience init(red: Int, green: Int, blue: Int, al: CGFloat) {
        assert(red >= 0 && red <= 255, "Invalid red component")
        assert(green >= 0 && green <= 255, "Invalid green component")
        assert(blue >= 0 && blue <= 255, "Invalid blue component")
        self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: al)
    }
    
    convenience init(netHex:Int, alpha: CGFloat) {
        self.init(red:(netHex >> 16) & 0xff, green:(netHex >> 8) & 0xff, blue:netHex & 0xff, al: alpha)
    }
}
// 沿著Y軸縮放, 縱向拉伸效果
- (CABasicAnimation *)createScaleYAnimation
 
{
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale.y"];
    animation.duration = 3.;
    animation.fromValue = @(1);
    animation.toValue = @(2.);
    return animation;
}
給圖片加濾鏡

extension UIImage
{
    //棕褐色復古濾鏡(老照片效果)
    func sepiaTone() -> UIImage?
    {
        let imageData = UIImagePNGRepresentation(self)
        let inputImage = CoreImage.CIImage(data: imageData!)
        let context = CIContext(options:nil)
        let filter = CIFilter(name:"CISepiaTone")
        filter!.setValue(inputImage, forKey: kCIInputImageKey)
        filter!.setValue(0.8, forKey: "inputIntensity")
        if let outputImage = filter!.outputImage {
            let outImage = context.createCGImage(outputImage, fromRect: outputImage.extent)
            return UIImage(CGImage: outImage)
        }
        return nil
    }
    
        //黑白效果濾鏡
    func noir() -> UIImage?
    {
        let imageData = UIImagePNGRepresentation(self)
        let inputImage = CoreImage.CIImage(data: imageData!)
        let context = CIContext(options:nil)
        let filter = CIFilter(name:"CIPhotoEffectNoir")
        filter!.setValue(inputImage, forKey: kCIInputImageKey)
        if let outputImage = filter!.outputImage {
            let outImage = context.createCGImage(outputImage, fromRect: outputImage.extent)
            return UIImage(CGImage: outImage)
        }
        return nil
    }
}
添加重力行為

在ViewController.swift文件中添加兩個屬性:


// UIKit物理引擎
var animator: UIDynamicAnimator!;
 
// 重力行為
var gravity: UIGravityBehavior!;

    注:代碼中感嘆號的作用這里不做過多介紹,請自行查閱官方文檔。

然后在viewDidLoad方法中再加入以下代碼:


// 實例化UIKit物理引擎類,作用于ViewController的View
animator = UIDynamicAnimator(referenceView: self.view);
 
// 實例化重力行為類,目前只作用于剛才創建的正方形View
gravity = UIGravityBehavior(items: [square]);
 
// 將重力行為添加到UIKit物理引擎類中
animator.addBehavior(gravity);

現在再編譯運行一下,這時我們可以看到這個藍綠色正方形開始做自由落體運動了,一直跌落出屏幕下邊緣然后消失。 
給UIKit組件添加移動吸附行為

import UIKit
 
class ViewController: UIViewController {
 
    @IBOutlet weak var imageView: UIImageView!
     
    var dynamicAnimator = UIDynamicAnimator()
    var snap:UISnapBehavior?
     
    override func viewDidLoad() {
        super.viewDidLoad()
         
        dynamicAnimator = UIDynamicAnimator(referenceView: self.view)
    }
     
    @IBAction func tapped(sender:AnyObject){
        //獲取點擊位置
        let tap = sender as! UITapGestureRecognizer
        let point = tap.locationInView(self.view)
         
        //刪除之前的吸附,添加一個新的
        if self.snap != nil {
            self.dynamicAnimator.removeBehavior(self.snap!)
        }
        self.snap = UISnapBehavior(item: self.imageView, snapToPoint: point)
        self.dynamicAnimator.addBehavior(self.snap!)
    }
 
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}
 NSMutableSet *showIndexes = [NSMutableSet set];
 
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
    
    
    //動畫1:
    if (![self.showIndexes containsObject:indexPath]) {
        [self.showIndexes addObject:indexPath];
        CGFloat rotationAngleDegrees = -30;
        CGFloat rotationAngleRadians = rotationAngleDegrees * (M_PI/ 180);
        CGPoint offsetPositioning = CGPointMake(-80, -80);
        
        
        CATransform3D transform = CATransform3DIdentity;
        transform = CATransform3DRotate(transform, rotationAngleRadians, 0.0,  0.0, 1.0);
        transform = CATransform3DTranslate(transform, offsetPositioning.x, offsetPositioning.y , 0.0);
        
        cell.layer.transform = transform;
        cell.alpha = 0.7;
        [UIView animateWithDuration:1 delay:0.0 usingSpringWithDamping:0.6f initialSpringVelocity:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            cell.layer.transform = CATransform3DIdentity;
            cell.layer.opacity = 1;
        } completion:nil];
    }
    
    
    /*
    //動畫2:
    if (![self.showIndexes containsObject:indexPath]) {
        [self.showIndexes addObject:indexPath];
        
        CATransform3D rotation;
        rotation = CATransform3DMakeRotation( (90.0*M_PI)/180, 0.0, 0.7, 0.4);
        rotation.m34 = 1.0/ -600;
        
        
        //2. Define the initial state (Before the animation)
        cell.layer.shadowColor = [[UIColor blackColor]CGColor];
        cell.layer.shadowOffset = CGSizeMake(10, 10);
        cell.alpha = 0;
        
        cell.layer.transform = rotation;
        cell.layer.anchorPoint = CGPointMake(0, 0.5);
        
        
        //3. Define the final state (After the animation) and commit the animation
        [UIView beginAnimations:@"rotation" context:NULL];
        [UIView setAnimationDuration:0.3];
        cell.layer.transform = CATransform3DIdentity;
        cell.alpha = 1;
        cell.layer.shadowOffset = CGSizeMake(0, 0);
        [UIView commitAnimations];
    }
     
     */
    
    /*
     //動畫3:
    if (![self.showIndexes containsObject:indexPath]) {
        [self.showIndexes addObject:indexPath];
        cell.layer.transform = CATransform3DTranslate(cell.layer.transform, 300, 0, 0);
        cell.alpha = 0.5;
        [UIView animateWithDuration:0.3 delay:0.0f usingSpringWithDamping:0.8f initialSpringVelocity:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            cell.layer.transform = CATransform3DIdentity;
            cell.alpha = 1;
        } completion:nil];
    }
     */
}
viewController里面有一個scrollView,該scrollView有一個headerView?,F在需要將scrollView的滾動contentOffset與headerView的變化聯系起來,實現headerView跟隨scrollView的contentOffset動態變化的效果。

 1、自定義headerView:

 ?。?)使用一個指針接收viewController里面的scrollView。

 ?。?)重寫willMoveToSuperview,使用KVO模式,為上述scorllView綁定一個Observer

    [self.scrollView addObserver:self forKeyPath:@"contentOffset" options:(NSKeyValueObservingOptionNew) context:nil];設置監聽者為headerView本身

 ?。?)其中headerView監聽函數為

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

    CGPoint newOffset = [change[@"new"] CGPointValue];

    [self updateSubViewsWithScrollOffset:newOffset];

}

這樣,在headerView里面可以實時得到scrollView的滾動contentOffSet,就可以做出與scrollView的contentOffset關聯的動畫效果。

2.viewController里面只需要將scrollView賦值給headerView暴露出來的接口就可以。
    func imageWithColor(_ color:UIColor) -> UIImage {
        
        let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
        
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()
        context?.setFillColor(color.cgColor)
        context?.fill(rect)
        
        let image:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }

// 思路1 : 將短視頻轉換為GIF圖片,用webView加載
let filePath = NSBundle.mainBundle().pathForResource("railway", ofType: "gif")

let gif = NSData(contentsOfFile: filePath!)

let webViewBG = UIWebView(frame: self.view.frame)

webViewBG.loadData(gif!, MIMEType: "image/gif", textEncodingName: String(), baseURL: NSUrl())
webViewBG.userInteractionEnabled = false;
self.view.addSubview(webViewBG)

// 思路2 :
直接播放短視頻.  
CGPoint center = cell.center;
CGPoint startCenter = center;
startCenter.y += LXD_SCREEN_HEIGHT;
cell.center = startCenter;

[UIView animateWithDuration: 0.5 delay: 0.35 * indexPath.item usingSpringWithDamping: 0.6 initialSpringVelocity: 0 options: UIViewAnimationOptionCurveLinear animations: ^{
    cell.center = center;
} completion: nil];

// Cell動畫, 類似微博發布彈出

iOS 當像素為1的寬度的線時顯示并不為1,原因是?

1 Point的線在非Retina屏幕則是一個像素,在Retina屏幕上則可能是2個或者3個,取決于系統設備的DPI。
iOS系統中,UIScreen,UIView,UIImage,CALayer類都提供相關屬性來獲取scale factor。
原生的繪制技術天然的幫我們處理了scale factor,例如在drawRect:方法中,UIKit自動的根據當前運行的設備設置了正切的scale factor。所以我們在drawRect: 方法中繪制的任何內容都會被自動縮放到設備的物理屏幕上。
基于以上信息可以看出,我們大部分情況下都不需要去關注pixel,然而存在部分情況需要考慮像素的轉化。
例如畫1個像素的分割線

看到這個問題你的第一想法可能是,直接根據當前屏幕的縮放因子計算出1 像素線對應的Point,然后設置線寬即可。
代碼如下:

1.0f / [UIScreen mainScreen].scale

表面上看著一切正常了,但是通過實際的設備測試你會發現渲染出來的線寬并不是1個像素。Why?

為了獲得良好的視覺效果,繪圖系統通常都會采用一個叫“antialiasing(反鋸齒)”的技術,iOS也不例外。
顯示屏幕有很多小的顯示單元組成,可以接單的理解為一個單元就代表一個像素。如果要畫一條黑線,條線剛好落在了一列或者一行顯示顯示單元之內,將會渲染出標準的一個像素的黑線。
但如果線落在了兩個行或列的中間時,那么會得到一條“失真”的線,其實是兩個像素寬的灰線。

規定:奇數像素寬度的線在渲染的時候將會表現為柔和的寬度擴展到向上的整數寬度的線,除非你手動的調整線的位置,使線剛好落在一行或列的顯示單元內。

如何對齊呢?

>在非高清屏上,一個Point對應一個像素。為了防止“antialiasing”導致的奇數像素的線渲染時出現失真,你需要設置偏移0.5 Point。
在高清屏幕上,要繪制一個像素的線,需要設置線寬為0.5個Point,同事設置偏移為0.25 Point。
如果線寬為偶數Point的話,則不要去設置偏移,否則線條也會失真。

這里給出一個宏定義:

#define SINGLE_LINE_WIDTH           (1 / [UIScreen mainScreen].scale)
#define SINGLE_LINE_ADJUST_OFFSET   ((1 / [UIScreen mainScreen].scale) / 2)  //繪制1像素的線

導航欄漸變:

let gradient = CAGradientLayer()
gradient.frame = CGRect(0, -20, kScreenWidth, 64)
gradient.startPoint = CGPoint(0, 0.5)
gradient.endPoint = CGPoint(1, 0.5)
gradient.colors = [UIColor(netHex: 0x005bea, alpha: 1).cgColor,UIColor(netHex: 0x00c6fb, alpha: 1).cgColor]
navigationController?.navigationBar.layer.addSublayer(gradient)
navigationController?.navigationBar.layer.insertSublayer(gradient, at: 0)

iOS 真機測試沒問題,打包上線一打開就閃退,maybe debug 和realease問題

2. 1 Performance: App Completeness (iOS) Guideline 2.1 - Information Needed
We have started the review of your app, but we are not able to continue because we need additional information about your app.

Next Steps

To help us proceed with the review of your app, please review the following questions and provide as much detailed information as you can.

- Does your app access any paid content or services?
- What are the paid content or services, and what are the costs?
- Who pays for the content or services?
- Where do they pay, and what's the payment method?
- If users create an account to use your app, are there fees involved?

Once you reply to this message in Resolution Center with the requested information, we can proceed with your review.

解決方案:直接回復- 
親愛的蘋果審核人員
我們的XXXXX App 不涉及到付費內容,不包括任何付費選項,也沒有收取費用的服務,如果用戶創建了一個帳戶來使用我們的App,完全不涉任何費用。非常抱歉我們沒有說明白,對你們的困惑我們深感抱歉。
Dear Apple reviewers
Our XXXXX App does not involve paid content, does not include any paid options, nor does it charge for a fee, and if the user creates an account to use our App, there is no charge at all. I'm sorry we are sorry to say that we are not confused.
5. 1.5 Legal: Privacy - Location Services Guideline 5.1.5 - Legal - Privacy - Location Services
Your app uses background location services but does not clarify the purpose of its use in the location modal alert as required in the [iOS Human Interface Guidelines](https://developer.apple.com/ios/human-interface-guidelines/ui-views/alerts/).
Please see attached screenshots for details.
Next Steps
To resolve this issue, please revise the NSLocationAlwaysUsageDescription value in the Info.plist to specify the intended purpose of using the user's location while the app is in the background.
Resources
For additional information and instructions on configuring and presenting an alert, please review the [Requesting Permission](https://developer.apple.com/ios/human-interface-guidelines/interaction/requesting-permission/) section of the iOS Human Interface Guidelines and the [Information Property List Key Reference]

定位權限問題: 在infoPlist文件中描述請求定位權限的用途, 沒有明確的描述使用后臺定位功能的目的。

Xcode一改變IB或者代碼就實時編譯刷新狀態, 選中Storyboard -> Editor -> Automatically Refresh Views 勾選 - 原文鏈接
https://segmentfault.com/q/1010000003958968

強制橫屏
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}
尺寸1  iPhone4s           3.5寸   640 * 960  640 * 1136 像素
尺寸2  iPhone 5 ~ 5s    4寸      640 * 1136 像素
尺寸3  iPhone6 ~ 7       4.7寸   750 * 1334 像素 
尺寸4  iPhone6P ~ 7P       5.5寸   1242 * 2208 像素 
尺寸5  iPhoneX  5.8寸  1125 * 2436 

iPad 9.7寸    768 * 1024
iPad 12.9寸 2048 * 2732 
    /**
     是否自動轉換方向
     
     - returns:
     */
    override func shouldAutorotate() -> Bool {
        return false
    }
    /**
     支持的設備方向
     
     - returns:
     */
    override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return  [UIInterfaceOrientationMask.LandscapeRight]
    }

微信支付注意點:
1.預支付訂單信息盡量在服務器后臺生成
2.(后臺)獲取到預支付會話ID后,要用時間戳參與進行二次簽名
3.(后臺)要返回簽名時所使用的時間戳
4.支付結果的處理. 在微信內完成支付操作,未返回APP之前,后臺會收到微信支付結果的回調.此時,從后臺查詢支付結果,并顯示對應的界面。點擊取消時,通知后臺該訂單已取消。
流程 —— > 設置商品訂單信息,發送請求 —- > 微信客戶端返回結果 — > 得到調起支付的必須參數 —> 調起微信客戶端進行支付 —> 支付回調結果
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=11_1 // 微信支付SDK下載地址
https://doc.open.alipay.com/doc2/detail.htm?treeId=54&articleId=104509&docType=1 //支付寶支付SDK下載地址
http://ios.jobbole.com/91789/ // 支付寶和微信支付

除了訪問Stack Overflow主站點外,你還可以使用標簽來瀏覽iOS開發相關主題:
http://stackoverflow.com/questions/tagged/objective-c
http://stackoverflow.com/questions/tagged/iphone
http://stackoverflow.com/questions/tagged/xcode
http://stackoverflow.com/questions/tagged/ios

1. 關于CocoaPods的一些低級的使用
2. Markdown語法說明
3. 關于collectionView的布局
4. 實時顯示iOS代碼編寫UI效果
5. 加速審核技巧 (英文原版)

本文章內容部分如有涉及違反原創或者版權問題, 請告知 @Weixin: 502086651  
因為這些知識片段都是在工作過程中查找的資料以及自己做的一些總結,用于自己記錄下來,并分享給有用的同行,希望能幫到你們。并無意違權。

如有不足之處,望大神們多多指正,在下也只是一個彩筆。嘿嘿。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容