Swift CoreData 基础向

创建项目使用coredata模版

框架创建

lifetrip.xcdatamodeld
Persistence.swift

使用

lifetrip.xcdatamodeld 添加实体

添加实体

  1. coredata保存与查询
    代理注入环境
    1
    2
    ContentView()
    .environment(\.managedObjectContext, PersistenceController.shared.container.viewContext)
初始化查询
1
2
3
4
5
6
@Environment(\.managedObjectContext) private var viewContext

@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \FootmarkEntity.startTime, ascending: false)],
animation: .default)
private var footmarks: FetchedResults<FootmarkEntity>
保存(新增)viewContext.save()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private func addItem() {
withAnimation {
let newItem = FootmarkEntity(context: viewContext)
// 实体赋值
let randomNumber:Int = Int(arc4random() % 100) + 1
newItem.id = String(randomNumber);
newItem.endTime = Date()
newItem.startTime = Date()
// 保存
do {
try viewContext.save()
} catch {
let nsError = error as NSError
fatalError("添加失败 \(nsError), \(nsError.userInfo)")
}
}
}
  1. 预览模式
    代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    struct LabelView_Previews: PreviewProvider {
    static var previews: some View {
    let labelEntity: LabelEntity = { () -> LabelEntity in
    let labelEntity = LabelEntity(context: PersistenceController.preview.container.viewContext)
    labelEntity.picture = UIImage(named: "nekosensei")!.pngData()
    return labelEntity
    }()
    return LabelCardView(labelEntity: labelEntity)
    }
    }
SwiftUI通过监听小键盘高度添加背景,通过点击背景隐藏小键盘

SwiftUI通过监听小键盘高度添加背景,通过点击背景隐藏小键盘

效果图

ExtensionAfterNavigationBackHidden.swift
1
2
3
4
5
6
7
8
9
10
extension UINavigationController: UIGestureRecognizerDelegate {
override open func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = self
}

public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return viewControllers.count > 1
}
}

swiftui 通过tabview实现图片查看器

效果图

  • 核心思路为通过tabview包裹图片 然后设置样式.tabViewStyle(PageTabViewStyle()).indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
  • 通过ZoomableScrollView组件实现图片的缩放,效果可以说是相当完美了
  • 感谢 jtbandes 真的是救我狗命
核心代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
struct ImageTabView: View {
@EnvironmentObject var imageTabViewEnviroment:ImageTabViewEnvironment

var body: some View {
VStack{
TabView(selection:$imageTabViewEnviroment.index) {
ForEach(0..<imageTabViewEnviroment.imageArray.count,id: \.self){ index in
ImageTabViewItemView(imageUrl: imageTabViewEnviroment.imageArray[index])
}
}
.tabViewStyle(PageTabViewStyle())
.indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
}
.edgesIgnoringSafeArea(.all)
}
}

private struct ImageTabViewItemView:View {
@State var scale: CGFloat = 1
@State private var dragOffset = CGSize.zero
@State var imageUrl: String
var body: some View{
VStack{
ZoomableScrollView {
MyKingfisherView(urlStr: imageUrl)
}
}
.frame(height:UIScreen.main.bounds.height)
.clipped()
}
}

struct ZoomableScrollView<Content: View>: UIViewRepresentable {
private var content: Content

init(@ViewBuilder content: () -> Content) {
self.content = content()
}

func makeUIView(context: Context) -> UIScrollView {
// set up the UIScrollView
let scrollView = UIScrollView()
scrollView.delegate = context.coordinator // for viewForZooming(in:)
scrollView.maximumZoomScale = 20
scrollView.minimumZoomScale = 1
scrollView.bouncesZoom = true

// create a UIHostingController to hold our SwiftUI content
let hostedView = context.coordinator.hostingController.view!
hostedView.translatesAutoresizingMaskIntoConstraints = true
hostedView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
hostedView.frame = scrollView.bounds
scrollView.addSubview(hostedView)

return scrollView
}

func makeCoordinator() -> Coordinator {
return Coordinator(hostingController: UIHostingController(rootView: self.content))
}

func updateUIView(_ uiView: UIScrollView, context: Context) {
// update the hosting controller's SwiftUI content
context.coordinator.hostingController.rootView = self.content
assert(context.coordinator.hostingController.view.superview == uiView)
}

// MARK: - Coordinator

class Coordinator: NSObject, UIScrollViewDelegate {
var hostingController: UIHostingController<Content>

init(hostingController: UIHostingController<Content>) {
self.hostingController = hostingController
}

func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return hostingController.view
}
}
}
swiftui简单的实现选项卡效果,同时初次加载

swiftui简单的实现选项卡效果,同时初次加载

pageView code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
struct PageView<SelectionValue, Content>: View where SelectionValue: Hashable, Content: View {
@Binding private var selection: SelectionValue
private let indexDisplayMode: PageTabViewStyle.IndexDisplayMode
private let indexBackgroundDisplayMode: PageIndexViewStyle.BackgroundDisplayMode
private let content: () -> Content

init(
selection: Binding<SelectionValue>,
indexDisplayMode: PageTabViewStyle.IndexDisplayMode = .automatic,
indexBackgroundDisplayMode: PageIndexViewStyle.BackgroundDisplayMode = .automatic,
@ViewBuilder content: @escaping () -> Content
) {
self._selection = selection
self.indexDisplayMode = indexDisplayMode
self.indexBackgroundDisplayMode = indexBackgroundDisplayMode
self.content = content
print(selection)
print(indexDisplayMode)
print(indexBackgroundDisplayMode)
}

var body: some View {
TabView(selection: $selection) {
content()
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: indexDisplayMode))
.indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: indexBackgroundDisplayMode))
}
}

extension PageView where SelectionValue == Int {
init(
indexDisplayMode: PageTabViewStyle.IndexDisplayMode = .automatic,
indexBackgroundDisplayMode: PageIndexViewStyle.BackgroundDisplayMode = .automatic,
@ViewBuilder content: @escaping () -> Content
) {
self._selection = .constant(0)
self.indexDisplayMode = indexDisplayMode
self.indexBackgroundDisplayMode = indexBackgroundDisplayMode
self.content = content
}
}

struct TestPageView1:View {
var body: some View{
Text("1")
.onLoad {
print("初次加载1")
}
}
}
struct TestPageView2:View {
var body: some View{
Text("2")
.onLoad {
print("初次加载2")
}
}
}
struct TestPageView3:View {
var body: some View{
Text("3")
.onLoad {
print("初次加载3")
}
}
}

struct Test_PageView:View {
@State var selection = 1
var body: some View {
VStack {
Text("Selection: \(selection)")
PageView(selection: $selection, indexBackgroundDisplayMode: .never) {
TestPageView1()
TestPageView2()
TestPageView3()
}
}
}
}
onLoad code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
struct ViewDidLoadModifier: ViewModifier {

@State private var didLoad = false
private let action: (() -> Void)?

init(perform action: (() -> Void)? = nil) {
self.action = action
}

func body(content: Content) -> some View {
content.onAppear {
if didLoad == false {
didLoad = true
action?()
}
}
}

}

extension View {

func onLoad(perform action: (() -> Void)? = nil) -> some View {
modifier(ViewDidLoadModifier(perform: action))
}

}
来自新世界的第十四期

来自新世界的第十四期

今日总结

动作

题外话

  • 主要时间还是浪费在找房上面,
    想和胜楠住一起,
    胜楠想要住公司附近,
    要么公司附近房租太贵、要么住处紧凑,
    相中南阳位置、胜楠不想挤地铁,
    虽然我认为只有5站并不远、但我并不喜欢勉强别人,
    实在不行只能考虑住到萧山、与陌生人合租,但我并不想,
  • 菊花找到工作,工资不菲,好消息
  • 大黑参与合租
  • lifetrip进度几乎结束
  • b站关于外星人拆机清灰的视频收到感谢,快的一批
来自新世界的第十三期

来自新世界的第十三期

今日总结

目标

  1. 8点之前起床。成功;
  2. 晚间拒绝垃圾食品。成功;
  3. lifetrip进度。成功:当日量完成;
  4. 手机时常控制。成功;

动作

题外话

找房的一天,胜楠公司附近的房租两室稍微好一点的要4000+。我找了一处距离他公司5站地铁的位置,那边3室整租只需要3000+。
看他怎么抉择吧,我在10m²的公寓住了一年,属实憋屈够了…接下来的一年希望可以舒适一些;

每周回顾的第二回

每周回顾的第二回

本周总结

  1. 本周开始了第一个工具类ios app 《life trip》规划已经做完,目标设立好,并且已经开发30%。
    但隐隐种种原因比较拖延,比如菊花工作,脚本,我要换房子,陪胜楠出去玩之类的。还完房子后工作会趋于稳定;
  2. 搞出一个抢票脚本,有待提高空间,收入150
  3. 看了电影helloworld
  4. 脱离舒适圈,第一次参加社交活动:密室逃脱
  5. 菊花612崩溃事件
  6. 在规划新住处

下周目标

  • 搬家 合同签订的26号
  • 尽可能完成app 杂事太多
来自新世界的第十二期
来自新世界的第十一期
来自新世界的第十期

来自新世界的第十期

今日总结

目标

周五、周六例行休息,放飞自我;

动作

  1. 帮助一个老哥抢票捡漏成功,收入150,分给烨董30元情报费用,有钱大家一起赚哈。这是第一次在互联网上赚到钱,有点意思,后续再想想如何将自己的技术变现;
  2. 看了helloworld电影,总体感受一般吧。冲着名字去的,感觉有点打破次元壁

    helloworld讲的故事和他的名字一样,是每个程序员绕不开的话题
    勤勤恳恳遵从他人的安排,终将成为用完就扔的工具人[Doge]
    toolsman:按照你说的做完会怎么样?
    boss:按照我说的做完就知道了。
    toolsman:我好了
    boss:sudo mv&rm

  3. 总体来说躺尸一天,傍晚时和龙导吹吹水,决定包养我去青海玩一下。当然,要做好一个提包小弟该有的本分[认真脸]

:D 一言句子获取中...