做个简单备忘。以后还得继续练习补充。因为中途接手了一个object c项目,所以这篇文章会揉杂一些 object c的内容。
下载Xcode,建立默认的 project,就可以直接运行了:
一、Project
Project interface分为 Storyboard 和 SwiftUI。这两者的区别为:
storyboards
和XIB
(Xml Interface Builder) 包含相当多的XML
语句,不容易阅读,也不容易编辑。storyboards
随着时间的推移越来越大。XIB
和Swift
是非常独立的东西,XIB
对Swift
代码不了解,而Swift
代码对XIB
也不了解。- SwiftUI 是一个只适用于
Swift
的框架。 - SwiftUI 代码比
storyboards
的XML
更容易阅读和管理。
最简单的创建:
- storyboard
- object c
- 不包括Tests
生成如下文件:
二、真机运行
如果是在真机上运行:
- 需要在xcode上配置证书
- 需要在手机上开启开发者模式:设置->隐私与安全性->开发者模式
- 需要在手机上信任开发者证书
以上都是免费的,不需要注册开发者账号。如果使用模拟器,则不用这么麻烦。
另外如果是从互联网上下载的代码,建议不要随意在真机上运行,有安全风险。
设置-> 通用->VPN与设备管理:
如果你的账号是团队的成员,我这边遇到好几个问题顺便记录一下(2023.08.20):
在账号中不显示团队信息,
大概率是在web配置页面,管理员没有配置你为开发者。
如果加入团队成为开发者还不行,那么先改成管理员,再恢复成开发人员也OK。
Failed to register bundle identifier The app identifier “xxx” cannot be registered to your development team because it is not available. Change your bundle identifier to a unique string to try again.
这里参考 Xcode Error: “The app ID cannot be registered to your development team.”
cd ~/Library/MobileDevice/Provisioning\ Profiles rm * Xcode > Preferences... > Accounts > click your Account and Team name > click Download Manual Profiles
三、概念理解
1. 官方文档
2. 核心概念
框架:
- Foundation
- Core Data
- Map Kit
- UIKit
- Core Motion
MVC:
3. object c
此部分来自https://www.runoob.com/w3cnote/objective-c-tutorial.html
- .h 头文件。头文件包含类,类型,函数和常数的声明。
- .m 源代码文件。这是典型的源代码文件扩展名,可以包含 Objective-C 和 C 代码。m代表Message。
- .mm 源代码文件。带有这种扩展名的源代码文件,除了可以包含Objective-C和C代码以外还可以包含C++代码。仅在你的Objective-C代码中确实需要使用C++类或者特性的时候才用这种扩展名。
Objective-C最大的特色是承自Smalltalk的消息传递模型(message passing),此机制与今日C++式之主流风格差异甚大。
-
C++里类别与方法的关系严格清楚,一个方法必定属于一个类别
obj.method(argument);
-
Objective-C,类别与消息的关系比较松散,调用方法视为对对象发送消息,所有方法都被视为对消息的回应。所有消息处理直到运行时(runtime)才会动态决定,并交由类别自行决定如何处理收到的消息。
[obj method: argument];
因此Objective-C具备类型动态绑定的能力。
我的个人观点,在objectc中,方法也可以叫做消息。对于它奇奇怪怪的方法写法,用消息的思维去理解更好。
Main函数还是程序的入口和出口。
hello world:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
}
return 0;
}
#import 可以保证头文件只被包含一次,无论此命令在文件中出现了多少次。
学习 Objective-C 以 Foundation框架为基础。
有了OC基础之后,还要学习Cocoa的Appkit框架,它包含了Cocoa的许多高级特性:用户界面元素、打印、颜色和声音管理、AppleScript支持等。
@符号:将c的字符串转换成oc的字符串,NSString。
@"hello"
基本类型:
//整型(int、short int、long int、unsigned int、unsigned short、unsigned long)
//sizeof() 计算数据(包括数组、变量、类型、结构体等)所占内存空间,用字节数表示
NSLog(@"基本数据类型---整型 int 字节数:%lu",sizeof(int));
NSLog(@"基本数据类型---短整型 short int 字节数:%lu",sizeof(short int));
NSLog(@"基本数据类型---长整型 long int 字节数:%lu",sizeof(long int));
NSLog(@"基本数据类型---无符号整型 unsigned int 字节数:%lu",sizeof(unsigned int));
NSLog(@"基本数据类型---无符号短整型 unsigned short 字节数:%lu",sizeof(unsigned short));
NSLog(@"基本数据类型---无符号长整型 unsigned long 字节数:%lu",sizeof(unsigned long));
//浮点型(float 、double 、long double)
NSLog(@"基本数据类型---实型-单精度 float 字节数:%lu",sizeof(float));
NSLog(@"基本数据类型---实型-双精度 double 字节数:%lu",sizeof(double));
NSLog(@"基本数据类型---实型-长双精度 long double字节数:%lu",sizeof(long double));
//字符型 (char)
NSLog(@"基本数据类型---字符型 char字节数:%lu",sizeof(char));
数组:
int a[5]={1,2,3,4,5,};
//取值
a[0]=1;a[1]=2;
char [3][2] = {{'q','w'},{'a','s'},{'z','x'}};
4. objectc类声明
.h文件多用,以关键字@interface作为开始,@end作为结束。
@interface MyObject : NSObject {
int memberVar1; // 实体变量
id memberVar2;
}
+(return_type) class_method; // 类方法,相当于静态方法
-(return_type) instance_method1; // 实例方法,相当于一般的类方法
-(return_type) instance_method2: (int) p1;
-(return_type) instance_method3: (int) p1 andPar: (int) p2;
@end
5. objectc方法声明
冒号(:)代表参数传递:
- (void) setColorToRed: (float)red Green: (float)green Blue:(float)blue; /*声明*/
[myColor setColorToRed: 1.0 Green: 0.8 Blue: 0.2]; /*调用*/
6. objectc 方法实现
以关键字@implementation作为区块起头,@end结尾。包含了public方法的实现,以及声明和实现private变量、方法。
7. objectc 方法调用/objectc 消息
为了避免声明过多的本地变量保存临时结果,Objective-C允许使用嵌套消息。每个嵌套消息的返回值可以作为其他消息的参数或者目标。
消息由中括号包裹。接收消息的对象在左边,消息(以及消息的参数)在右边。例如,给 myArray 变量传递消息insertObject:atIndex: 消息,使用如下的语法:
[myArray insertObject:anObj atIndex:0];
8. objectc 属性
@property,与@synthesize配对使用,用来让编译器自动生成与数据成员同名的方法声明。
@property (参数1,参数2,参数3)类型名字;
- 参数1:atomicity(nonatomic) atomicity的默认值是atomic,读取函数为原子操作
- 参数2:setter/getter方法(assign/retain/copy) assign是简单数据类型(不是NS对象), retain 是指针拷贝,copy 是内容拷贝。assign/retain/copy 代表赋值的方式
- 参数3:读写属性(readwrite/readonly)
- readonly关键字代表setter不会被生成, 不可以和 copy/retain/assign组合使用。
@interface Person : NSObject {
@public
NSString *name;
@private
int age;
}
@property(copy) NSString *name;
@property(readonly) int age;
-(id)initWithAge:(int)age;
@end
访问:
self.myString = @"Test";
objectc 重要数据类型
- NSString字符串
- CGfloat 浮点值的基本类型
- NSInteger 整型
- BOOL 布尔型
objectc 打印日志
NSlog(@"");
objectc 创建实例
MyObject * my = [[MyObject alloc] init];
MyObject * my = [MyObject new];
MyClass *objectName = [[MyClass alloc]init] ;
[objectName simpleInstanceMethod];
objectc 协议
@protocol Locking
- (void)lock;
- (void)unlock;
@end
@interface SomeClass : SomeSuperClass <Locking>
@end
@implementation SomeClass
- (void)lock {
}
- (void)unlock {
}
@end
其它
-
数组
NSMutableArray *aMutableArray = [[NSMutableArray alloc]init]; [anArray addObject:@"firstobject"]; NSArray *aImmutableArray = [[NSArray alloc] initWithObjects:@"firstObject",nil];
-
字典
NSMutableDictionary*aMutableDictionary = [[NSMutableArray alloc]init]; [aMutableDictionary setObject:@"firstobject" forKey:@"aKey"]; NSDictionary*aImmutableDictionary= [[NSDictionary alloc]initWithObjects:[NSArray arrayWithObjects: @"firstObject",nil] forKeys:[ NSArray arrayWithObjects:@"aKey"]];
-
分类
.h和.m文件的简单示例,帮助理解object c的格式:
- .h里的变量和方法是public,.m里的变量和方法是private.
- 例子比较老了,来自《Stanford CS193p Fall 2013》
四、xcode 简单功能
右上角的+用得最多了,添加各种组件。
asset目录里有很多不同尺寸的图:
素材
可以方便导出各种格式尺寸的图。
- 应用图标Logo 转换+iOS一堆尺寸图一键导出:App Icon Generator
- 画图素材网站:https://www.canva.cn/
- GitHub Awesome :https://github.com/dkhamsing/open-source-ios-apps
- 一个 udemy 教材相关链接:https://www.appbrewery.co/p/ios-course-resources/
编辑页面
选择 Assistant 可以将代码和界面放一起:
关联图标和代码:IBOutlet
声明组件和Action可以用拖拽的方式,ctrl+拖动
关联关系可以在图形上右键查看:
五、自适应布局
constraints,指定item和边缘的距离。
alignment/pinning
iOS里的stack view组件可以类比为html中的div组件。
view controller里的文件视图类似于photoshop里的图层反过来。
stack view
上图右下角的最右边那个收纳的图标。
六、纯代码生成view和controller
这样在图形化界面里我们就根本看不见这个view了,没办法用拖拽的方式给它添加东西。
- 新建一个
swift
文件:
-
命名为ViewController
secondVC,改一下 import 为
UIKit` -
定义一些基本的变量保存数据
-
override func viewDidLoad
-
定义一个组件,例如 UILabel
-
在上一个页面的
ViewController
里给 secondVC 的变量赋值 -
在上一个页面的
ViewController
里self.present(secondVC, animated:true, completion: nil)
七、拖拽式生成view并绑定controller
在图形界面新建一个viewController
新建一个cocoa touch class
:
然后在 storyboard 里点一下还没有绑定 vc 的图形:
选择之后就可以看到它绑定好了。
八、生成view间关联:segues
设定segues的identifier名字:
然后在代码中触发这个切换:
self.performSegue(withIdentifier: "testSeg", sender: self)
同时,在前一个 controller 里我们可以做这个view 在切换前的准备工作:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
if segue.identifier == "testSeg" {
let destinationVC = segue.destination as! ResultViewController
destinationVC.bmiValue = calculatorBrain.getBMIValue()
destinationVC.advice = calculatorBrain.getAdvice()
destinationVC.color = calculatorBrain.getColor()
}
}
在新的view里返回上一个view: dismiss
@IBAction func recalculatePressed(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
}
在运行时可以用3D的方式查看图层,点击中间那个图层图标:
navigation controller
先点击黄色图标,再点击再菜单栏上选择 Editor->Embed In->Navigation Controller
,
navitationItem.hidesBackButton = true
九、iOS13新增图标
十、暗色模式与矢量图
Image Set -> Appearance -> 设置明色与暗色
Image Set-> Resizing -> 保留矢量信息