小编Qua*_*ntm的帖子

使用 Apple 的新组合框架时如何防止强引用循环(.assign 导致问题)

我不太明白如何在类中正确存储订阅者,以便它们持续存在但不会阻止对象被取消初始化。这是对象不会取消初始化的示例:

import UIKit
import Combine

class Test {
    public var name: String = ""

    private var disposeBag: Set<AnyCancellable> = Set()

    deinit {
        print("deinit")
    }

    init(publisher: CurrentValueSubject<String, Never>) {
        publisher.assign(to: \.name, on: self).store(in: &disposeBag)
    }
}

let publisher = CurrentValueSubject<String, Never>("Test")

var test: Test? = Test(publisher: publisher)
test = nil

Run Code Online (Sandbox Code Playgroud)

当我assign用 a替换sink(在其中我正确声明[weak self])时,它实际上确实正确地进行了 deinit(可能是因为assign访问self的方式会导致问题)。

例如,如何在使用时防止强引用循环.assign

谢谢

swift combine

23
推荐指数
2
解决办法
5309
查看次数

SwiftUI 和 MVVM - 模型和视图模型之间的通信

我一直在试验使用的 MVVM 模型,SwiftUI但有些东西我还不太明白。

SwiftUI使用@ObservableObject/@ObservedObject检测视图模型中触发body属性重新计算以更新视图的更改。

在 MVVM 模型中,这是视图和视图模型之间的通信。我不太明白的是模型和视图模型是如何通信的。

当模型发生变化时,视图模型应该如何知道这一点?我想到了手动使用新Combine框架在模型内部创建视图模型可以订阅的发布者。

但是,我创建了一个简单的示例,我认为该示例使这种方法非常乏味。有一个模型称为Game保存Game.Character对象数组。一个角色有一个strength可以改变的属性。

那么如果一个视图模型改变strength了一个角色的那个属性呢?为了检测这种变化,模型必须订阅游戏中的每一个角色(可能还有很多其他的东西)。是不是有点过分了?或者有很多发布者和订阅者是正常的吗?

还是我的示例没有正确遵循 MVVM?我的视图模型不应该将实际模型game作为属性吗?如果是这样,什么是更好的方法?

// My Model
class Game {

  class Character {
    let name: String
    var strength: Int
    init(name: String, strength: Int) {
      self.name = name
      self.strength = strength
    }
  }

  var characters: [Character]

  init(characters: [Character]) {
    self.characters = characters
  }
}

// ...

// My view model
class ViewModel: …
Run Code Online (Sandbox Code Playgroud)

swift swiftui combine

22
推荐指数
3
解决办法
2万
查看次数

SwiftData - 如何在 SwiftUI 之外观察数据库的更改?

我有一个简单的例子。Trip我从数据库中获取所有对象:

import SwiftData

@Model
class Trip {
    var name: String
}

func fetch() {
    let container = ModelContainer(for: Trip.self)
    let context = ModelContext(container)
    let fetchDescriptor = FetchDescriptor<Trip>()
    let trips = try! context.fetch(fetchDescriptor)
    
    // Store it somewhere ...
}
Run Code Online (Sandbox Code Playgroud)

如何观察 trips 数组的变化?我知道数组中的各个对象是可观察的,并且当某些内容提交到数据库时会发生变化。但是,如果顺序发生变化,或者某些行程被删除或插入新行程怎么办?我找不到一种机制来通知这一点。

我发现的唯一方法是@Query在 SwiftUI 中使用新的属性包装器。但我想在单独的类中观察 SwiftUI 环境之外的变化。有没有办法做到这一点?

swift swift-data

17
推荐指数
0
解决办法
2393
查看次数

快速重新创建iOS 13的共享表单模式(不是共享表单本身,而是呈现方式)

有没有一种方法可以轻松地重新创建ios 13的新共享表的模式表示样式?(起初,它只是中途显示,您可以向上滑动以使其成为“完整的”模态表)。我可以使用完全自定义的显示形式和内容来做到这一点,但是对于此行为是否有“本机” API,因此您不必不必使用自定义代码?

谢谢!

在此处输入图片说明

ios swift

14
推荐指数
2
解决办法
466
查看次数

从pdf数据中提取单个页面(或页面范围)而不加载整个pdf(有时需要太多RAM)

PDFKit在swift中使用,您可以使用PDFDocument打开pdf文件.这很简单,效果很好.但我正在构建一个适合我需求的自定义pdf查看器(适用于漫画书pdf),我遇到了一个问题.在查看器中,我不需要将整个pdf文件存储在内存中.我一次只需要几页.

此外,pdfs仅包含图像.没有文字或任何东西.

实例化a时PDFDocument,整个pdf数据被加载到内存中.如果你有非常庞大的pdf文件(超过1GB),这不是最佳的(并且可能会在某些设备上崩溃).据我所知,PDFKit中没有办法只加载pdf文档的部分内容.

我能做些什么吗?我还没有找到一个可以做到这一点的swift/obj-c库(虽然我真的不知道搜索它的正确关键字).

我的解决方法是预处理pdf并使用在.documents director(或类似)中将每个页面保存为图像FileManager.这将导致大量文件,但会解决内存问题.不过,我不确定我喜欢这种方法.

更新:

所以我做了@Prcela和@Sahil Manchanda提出的建议.它似乎现在正在发挥作用.

@yms:嗯,确实可能是个问题.当只有图像时,这甚至会发生吗?在pdf中没有任何其他内容.

@ Carpsen90:它们是本地的(保存在文档目录中).

编辑:我没有接受下面的答案,或给它赏金.这是自动的.它没有解决问题.它仍然将整个PDF加载到内存中!

pdf ios swift

12
推荐指数
1
解决办法
931
查看次数

在列表中的部分之间移动项目时,SwiftUI 奇怪的行为

所以我一直在尝试制作一个组件swiftUI,它允许您List在部分之间移动项目。

我准备了一个包含两个部分的示例:“第一列表”和“第二列表”。每当您点击一个项目时,它就会交换部分。这是一个屏幕截图:

在此处输入图片说明

当我点击“第一个列表:1”时,它会正确移动到第二部分:

在此处输入图片说明

但是,它的名称现在应该更改为“第二个列表:1”,因为我命名这些部分中的元素的方式(请参阅下面的代码)。所以这很奇怪。但它变得奇怪:

当我现在点击第二部分中的“第一个列表:1”时,会发生这种情况:

在此处输入图片说明

它没有正确交换回来。它只是被复制了,但这次重复的名称实际上是正确的。

考虑到下面的代码,我不明白这是怎么可能的。似乎以swiftUI某种方式重用该项目,即使它重新呈现视图?它似乎也重用了.onTapGesture闭包,因为应该将项目放回第一部分的方法实际上从未被调用过。

知道这里发生了什么吗?以下是该问题的完整示例:

import SwiftUI
import Combine

struct TestView: View {
    @ObservedObject var viewModel: ViewModel

    class ViewModel: ObservableObject {
        let objectWillChange = PassthroughSubject<ViewModel,Never>()

        public enum List {
            case first
            case second
        }

        public var first: [Int] = []
        public var second: [Int] = []

        public func swap(elementWithIdentifier identifier: Int, from list: List) {
            switch list {
            case .first:
                self.first.removeAll(where: {$0 == identifier})
                self.second.append(identifier)
            case .second:
                print("Called")
                self.second.removeAll(where: …
Run Code Online (Sandbox Code Playgroud)

swift swiftui

10
推荐指数
1
解决办法
971
查看次数

SwiftUI - 在列表中的视图内触发的动画也不会为列表设置动画

我有一个List显示两个Views相同类型的。当您点击其中一个视图时,它们会通过动画改变高度。

但是,List嵌入的这些视图不会动画,这会导致丑陋的故障,因为List行的高度会立即更改,而该行内的实际视图是动画的:

在此处输入图片说明

我怎样才能制作List动画?我尝试向其添加.animation修饰符,但这没有任何作用。

我也不想将tapGesture视图移出。视图应该是自包含的,而不是依赖其他视图来控制它(我认为这就是 MVVM 的意义所在)

谢谢!

import SwiftUI

struct SubView: View {
    @State var change: Bool = false

    var body: some View {
        Rectangle()
            .frame(width: 200, height: change ? 300 : 200)
            .foregroundColor(Color.red)
            .onTapGesture {
                withAnimation {
                    self.change.toggle()
                }
        }
    }
}

struct Test: View {

    var body: some View {
        List {
            SubView()
            SubView()
        }
    }
}

struct Test_Previews: PreviewProvider {
    static var previews: …
Run Code Online (Sandbox Code Playgroud)

ios swift swiftui

10
推荐指数
1
解决办法
1103
查看次数

IOS 13 Combine Framework-@Published不起作用(“未知属性'Published'”)

我观看了WWDC 2019会议``实践结合''(https://developer.apple.com/videos/play/wwdc2019/721/)。

在视频中,他们使用以下语法创建了发布者:

@Published var someName: String = ""
Run Code Online (Sandbox Code Playgroud)

他们这样做是为了someName成为出版商。但是,Xcode不喜欢这种语法,并给我一个错误:

未知属性“已发布

我不知道为什么。我正在macOS Catalina上使用Xcode 11 beta。

有任何想法吗?

ios swift combine

9
推荐指数
1
解决办法
1532
查看次数

自定义视图 - self.frame不正确?

所以我有一个自定义的UIView类

class MessageBox: UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)
        createSubViews()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        createSubViews()
    }
    func createSubViews() {

        let testView = UIView(frame: self.frame)
        testView.backgroundColor = UIColor.brown
        self.addSubview(testView)
    }
}
Run Code Online (Sandbox Code Playgroud)

我在故事板中添加了一个UIView并给它一些约束:

从顶部100(superview),从左和右0,高度是180

但是当我运行应用程序时,我在代码中创建的棕色子视图是很大的.我self.frame在我的自定义视图中打印,结果表明框架是(0,0,1000,1000).但为什么?我设置约束,应该是这样的(0,0,deviceWith, 180).

在此输入图像描述

我做错了什么?

编辑:这是我的故事板设置:

在此输入图像描述

storyboard uiview ios swift

8
推荐指数
1
解决办法
9752
查看次数

XCode - 如何重置/“删除”从 Xcode 运行的 mac os 应用程序(类似于删除 ios 模拟器中的应用程序)?

使用 iOS 模拟器时,我只需删除该应用程序并重新运行该应用程序即可重新开始。对于 macOS 应用程序,这是如何完成的?我找不到它。“DerivedData”内有一个项目文件夹,但删除它也会扰乱整个项目,我必须重新获取所有依赖项和内容。

谢谢!

macos xcode

8
推荐指数
1
解决办法
1441
查看次数

标签 统计

swift ×9

ios ×5

combine ×3

swiftui ×3

macos ×1

pdf ×1

storyboard ×1

swift-data ×1

uiview ×1

xcode ×1