//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线图组件,都是比较不错的。可以学习下 具体使用还要修改:
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 开发学习路线
链接地址
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。现在需要将scrollView的滚动contentOffset与headerView的变化联系起来,实现headerView跟随scrollView的contentOffset动态变化的效果。
1、自定义headerView:
(1)使用一个指针接收viewController里面的scrollView。
(2)重写willMoveToSuperview,使用KVO模式,为上述scorllView绑定一个Observer
[self.scrollView addObserver:self forKeyPath:@"contentOffset" options:(NSKeyValueObservingOptionNew) context:nil];设置监听者为headerView本身
(3)其中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
因为这些知识片段都是在工作过程中查找的资料以及自己做的一些总结,用于自己记录下来,并分享给有用的同行,希望能帮到你们。并无意违权。
如有不足之处,望大神们多多指正,在下也只是一个彩笔。嘿嘿。
网友评论