小编Jon*_*han的帖子

委托模式是 SwiftUI 中的好方法吗?

我正在将 iOS 应用程序从 UIKit 转换为 SwiftUI。我有一个UIViewController显示带有不同按钮的视图。它UIViewController有一个符合特定协议的委托。对于每个按钮的操作,我调用其委托的方法。这里没什么特别的,这是我们都知道使用 UIKit 进行 iOS 开发的典型委托模式。

我的问题是:对于 SwiftUI 来说这仍然是一个好的方法吗?我完全可以在我的 SwiftUI 应用程序中转换这种模式(我已经这样做了。编辑:正如评论中提到的,这不是一个好主意!)。但我想知道这种委托模式是否仍然是一种好方法,或者是否有其他方法可以做到这一点(也许可以使用绑定?)。是否建议在 SwiftUI 应用程序中使用此模式?

这是一个简化的代码示例:

protocol MyCustomViewDelegate {
    func buttonATapped()
}

struct MyCustomView: View {
    public var delegate: MyCustomViewDelegate?
    var body: some View {
        Button("Button A") {
            if let delegate = delegate {
                delegate.buttonATapped()
            }
        }
    }
}

struct ContentView: View, MyCustomViewDelegate {

    var body: some View {
        MyCustomView(delegate: self)
    }

    func buttonATapped() {
        // Do something
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:请不要使用以前的实现!

delegates ios swift swiftui

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

SwiftUI:在打开“sheet”的情况下重新打开应用程序时,点击时出现奇怪的偏移

我面临着一种奇怪的行为,看起来确实像 SwiftUI bug。

当我打开应用程序并.sheet重新打开它时,来自父级的所有内容都会有一个点击偏移量。这很难解释(英语不是我的母语)所以这是一个非常简单的例子:

struct ContentView: View {
    @State private var isOpen = false
    var body: some View {
        Button(action: {
            isOpen.toggle()
        }, label: {
            Text("Open sheet")
                .foregroundColor(.white)
                .padding()
                .background(.blue)
        })
        .sheet(isPresented: $isOpen, content: {
            Text("Sheet content")
        })
    }
}
Run Code Online (Sandbox Code Playgroud)

要重现该问题,请按照下列步骤操作:

  1. 点击蓝色按钮顶部边框的正下方Open sheet:工作表按预期打开。
  2. 当工作表打开时,关闭应用程序(返回 Springboard,在 iOS 模拟器上使用 cmd+shift+H)。
  3. 重新打开应用程序。您仍在工作表视图中。
  4. 关闭工作表。您将返回到带有蓝色按钮的主视图。这是错误:
  5. 再次点击顶部边框正下方的蓝色按钮顶部。什么都没发生。您必须单击下面的几个像素。有一个偏移量使得主视图上的所有可点击项目未对齐。

有人也见过这个错误吗?我做错了什么吗?

其他注意事项:

  • 从主视图关闭应用程序时,该错误不会出现。即使错误出现并且我从主视图关闭应用程序并重新打开,错误也会消失。
  • 如果我使用 a.fullScreenCover代替.sheet,则不会出现该错误。
  • 它确实看起来像一个.sheets打开的错误。

编辑:
我尝试了两种解决方法,但都不起作用:

  • 将 嵌入Button到外部视图中。
  • Button仅替换为Text并添加.onTapGesture{ ... } …

user-interface ios swiftui

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

SwiftUI 将 SF 符号作为文本与文本对齐

我需要在视图中显示 SF 符号(图像)和文本(作为标题)。由于文本可能很长,我希望它在第二行的图像下方通过。

预期结果(几乎!):

在此输入图像描述

我首先尝试HStack使用图像和文本。但文本不会位于图像下方:第二行以左侧“填充”(对应于左侧图像空间)开始。

所以我做了这段代码(以获得之前的屏幕截图):

HStack(alignment:.top) {
    Text(Image(systemName: "circle.hexagongrid.circle"))
        .font(.caption)
        .foregroundColor(.pink)
    +
    Text("A long text as example")
        .font(.title2).bold()
        .foregroundColor(.pink)
}
.frame(width:140)
Run Code Online (Sandbox Code Playgroud)

但我想将图像与第一行的中心对齐。图像中心应垂直位于 顶部A和底部的中间g

重要的是我的第二条(以及更多)条线要穿过我的图像下方。而且我不想要更大的图像字体。

text image alignment swiftui

5
推荐指数
3
解决办法
4569
查看次数

UIActivityViewController,无法同时满足约束,在为 iOS 7.x 编译时在设备 8.x 上

我有一个UIActivityViewController显示在UIViewController(此处命名为 viewCon)上的:

// items contains text and/or image
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:nil];
activityViewController.excludedActivityTypes = @[UIActivityTypePostToWeibo, UIActivityTypeAssignToContact];

[viewCon presentViewController:activityViewController animated:YES completion:NULL];
Run Code Online (Sandbox Code Playgroud)

我正在使用 Xcode 6.1。我的应用程序的部署目标为 7.0。我在两部物理 iPhone(5S (8.0.2) 和 6 (8.1))上运行它。
当我在物理设备上(而不是在模拟器上)为 iOS 7.x 编译我的应用程序时,UIActivityViewController会显示并工作,但它会出现在所有屏幕上(高度太大),并且此日志消息打印在输出中:

Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. Try this:
(1) look at each constraint and try to figure out which you don't expect;  
(2) …
Run Code Online (Sandbox Code Playgroud)

objective-c ios uiactivityviewcontroller

3
推荐指数
1
解决办法
1387
查看次数

MapKit : 添加 MKPolyline 隐藏 MKTileOverlay

MKMapView正在处理MKTileOverlay来自本地数据库的显示图块。它工作正常。
然后我用来MKDirections获得两个坐标之间的方向并绘制这样的路线:

MKRoute *route = response.routes.lastObject;
MKPolyline *polyline = route.polyline;

// Draw path on overlay
[self.mapView insertOverlay:polyline aboveOverlay:self.tileOverlay];
Run Code Online (Sandbox Code Playgroud)

但是当我缩放以查看线条时,它看起来没有平铺背景(通常从MKTileOverlay(存储到self.tileOverlay)加载)。我加入了一个图像以更好地查看。

我还制作了此代码来呈现叠加层:

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
    if ([overlay isKindOfClass:[MKTileOverlay class]]) {
        return [[MKTileOverlayRenderer alloc] initWithTileOverlay:overlay];
    }
    else if ([overlay isKindOfClass:[MKPolyline class]]) {
        MKPolylineRenderer *lineView = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
        lineView.strokeColor = [UIColor greenColor];
        lineView.lineWidth = 3;
        return lineView;
    }
    return nil;
}
Run Code Online (Sandbox Code Playgroud)

这就像渲染线的“瓷砖”隐藏从MKTileOverlay. 我怎样才能:
- 指定MKPolyline叠加层必须是透明的?
- …

objective-c mkpolyline mktileoverlay

3
推荐指数
1
解决办法
858
查看次数

单元格在UICollectionView中排序

我需要创建一个UICollectionView不同大小的单元格(1x1,2x2,2x1,3x2.5).我已经编码添加单元格,具体取决于它们使用的大小collectionView:layout:sizeForItemAtIndexPath:.

这是预期的结果(单元格1和3必须位于单元格2的左侧):
在此输入图像描述

但目前的结果是:
在此输入图像描述

我(丑陋的)当前代码是(self.cellSize =屏幕宽度/ 3):

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

    CGFloat size = self.cellSize;

    if (indexPath.item == 0) {
        return CGSizeMake(self.cellSize * 3.f, self.cellSize * 2.5f);
    }

    if (indexPath.item == 1) {
        return CGSizeMake(self.cellSize, self.cellSize);
    }

    if (indexPath.item == 2) {
        return CGSizeMake(self.cellSize * 2.f, self.cellSize * 2.f);
    }

    if (indexPath.item == 3) {
        return CGSizeMake(self.cellSize, self.cellSize);
    }

    if (indexPath.item == 4) {
        return CGSizeMake(self.cellSize * 2.f, self.cellSize);
    }

    if (indexPath.item == …
Run Code Online (Sandbox Code Playgroud)

objective-c ios uicollectionview

2
推荐指数
1
解决办法
991
查看次数

来自plist文件的NSArray或NSDictionary

在一个方法中,我需要读取一个NSArrayNSDictionary一个plist文件.

这是我的问题:当我不知道它是否是数组或字典时,如何从文件创建NSArrayOR ?NSDictionaryplist

我知道我可以做:

NSArray *myArray = [NSArray arrayWithContentsOfFile:filePath];
Run Code Online (Sandbox Code Playgroud)

要么

NSDictionary *myDico = [NSDictionary dictionaryWithContentsOfFile:filePath];
Run Code Online (Sandbox Code Playgroud)

但我不知道filePath是否包含a NSArray或a NSDictionary.我想要像:

id myObject = [... ...WithContentOfFile:filePath];
Run Code Online (Sandbox Code Playgroud)

有人可以帮助我并给我最好的方法吗?

objective-c nsdictionary plist nsarray ios

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