//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
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 開發學習路線
鏈接地址
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
因為這些知識片段都是在工作過程中查找的資料以及自己做的一些總結,用于自己記錄下來,并分享給有用的同行,希望能幫到你們。并無意違權。
如有不足之處,望大神們多多指正,在下也只是一個彩筆。嘿嘿。