SwiftUI-为什么在macOS上更改选项卡时TabView及其内容有时不刷新?

时间:2019-12-23 06:24:02

标签: swift macos swiftui swiftui-bug

我正在尝试使用SwiftUI在macOS上创建选项卡式应用程序,而TabView则存在一个奇怪的问题。

当我有两个分别带有TextField的标签并将其文本状态保存到各自的私有变量时,会发生奇怪的事情:当我从标签A 切换到标签B 标签A TextField中输入文字后,标签指示符显示我仍在标签A 上,但内容显示标签B 的内容。当我再次单击标签B 的按钮时,它仍会显示标签B 的内容。此外,当我随后按下 tab A 的按钮时,它将显示 tab A 的内容,但该标签的指示器仍显示我在标签B

我可能做错了什么?

以下是说明我的问题的示例:

import SwiftUI

struct ContentView: View {
    var body: some View {
        TabView
            {
                TabAView()
                    .tabItem({Text("Tab A")})
                TabBView()
                    .tabItem({Text("Tab B")})
        }
    }
}

struct TabAView: View {
    @State private var text = ""
    var body: some View {
        VStack{
            Text("Tab A")
            TextField("Enter", text: $text)
        }
    }
}

struct TabBView : View {
    @State private var text = ""
    var body: some View {
        VStack {
            Text("Tab B")
            TextField("Enter", text: $text)
        }
    }
}

以下是发生的问题的屏幕截图: And here is a GIF of the issue occurring

1 个答案:

答案 0 :(得分:2)

这绝对是SwiftUI的TabView实现中的错误。但是您可以通过绑定到TabView选择并手动设置当前选项卡来轻松解决此问题,如下所示:

#include <iostream>

class IFirstClass
{
public:
    virtual void perform(std::string name) = 0;
};

class ISecondClass
{
public:
    virtual void furtherPerform(std::string name, std::string desc) = 0;
};

class FirstClass : public IFirstClass
{
public:
    virtual void perform(std::string name)
    {
        std::cout << "Performing action: " << name << "\n";
    }
};

class SecondClass : public ISecondClass
{
public:
    virtual void furtherPerform(std::string name, std::string desc)
    {
        std::cout << "Performing action: " << name << " with description: " << desc << "\n";
    }
};

class Adapter : public IFirstClass
{
private:
    SecondClass& derived;
public:
    Adapter(SecondClass& derived) : derived{ derived }
    {

    }
    virtual void perform(std::string name)
    {
        derived.furtherPerform(name, ? );
    }
};
int main()
{
    FirstClass a;
    SecondClass b;
    Adapter c(b);
    c.perform("Name", "Description");
}

仅当用户在TextField具有焦点的情况下更改选项卡时,此错误才会显现。

如果您对代码进行了上述更改,它将按预期工作。

Screen capture of fix working