AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / user-777861

Andrei Herford's questions

Martin Hope
Andrei Herford
Asked: 2025-04-11 17:24:35 +0800 CST

Como .frame(maxHeight: 100) é calculado quando usado em uma View dentro de uma ScrollView?

  • 5

Resumo: Por que tem Color.red.frame(maxWidth: 500)uma ScrollViewaltura de visualização de pixels? Por que não 500px ou 0px?


Pelo que entendi sobre posicionamento e dimensionamento do SwiftUI, cada visualização é questionada sobre o tamanho desejado. A visualização responde com seus requisitos máximos e a visualização pai lhe dá o máximo de espaço possível.

  • Colorpor padrão usa o máximo de espaço possível.
  • O uso de .frame(maxHeight: x)on Colorlimita isso a x pixels
  • Nos exemplos a seguir, todas as três Colorvisualizações gostariam de ter um maxHeight de 500px. No entanto, como o espaço disponível é menor que 1500px, ele é dividido igualmente entre as visualizações, que são menores:

Exemplo:

var body: some View {
    VStack {
        Color.red
            .frame(maxHeight: 500)
        
        Color.yellow
            .frame(maxHeight: 500)
        
        Color.green
            .frame(maxHeight: 500)
    }
}

insira a descrição da imagem aqui

Mas, ao posicionar as Colorvisualizações dentro de um objeto, ScrollViewelas são renderizadas com uma altura de apenas alguns pixels. Por quê?

Não deveria ScrollViewoferecer altura infinita, o que permitiria que as Colorvisualizações usassem sua altura total de 500px cada?

Ou ele ScrollViewdá o mínimo de espaço possível às suas subvisualizações? Nesse caso, eu entenderia se as Colorvisualizações fossem reduzidas a 0px.

Mas de onde vem essa pequena altura (talvez 10px?)? Como isso é calculado?

var body: some View {
    ScrollView {
        VStack {
            Color.red
                .frame(maxHeight: 500)
            
            Color.yellow
                .frame(maxHeight: 500)
            
            Color.green
                .frame(maxHeight: 500)
        }
    }
}

insira a descrição da imagem aqui

Sei que posso resolver "o problema" usando " frame(height: )em vez disso". No entanto, só quero entender como o SwiftUI calcula a altura neste caso.

  • 1 respostas
  • 39 Views
Martin Hope
Andrei Herford
Asked: 2025-04-08 15:45:44 +0800 CST

Como aplicar o plano de fundo do Content ViewController ao SafeArea inferior no UINavigationController?

  • 5

Ao portar meu aplicativo existente baseado em UIKit para SwiftUI, tenho dificuldade com uma tarefa simples:

A UIViewControllerRepresentablesegura um UINavigationController.

Os UINavigationControllerVCs são exibidos com cores de fundo diferentes. Essas cores não são aplicadas à área segura inferior. Como posso alterar isso para que a área segura tenha a cor do VC filho ativo?

insira a descrição da imagem aqui

struct SomeSheetContent: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> UIViewController {
        let firstVC = UIViewController()
        firstVC.view.backgroundColor = .green
        firstVC.title = "First VC"
        firstVC.edgesForExtendedLayout = [.all]
        firstVC.extendedLayoutIncludesOpaqueBars = true

        let button = UIButton(type: .system)
        button.setTitle("Next", for: .normal)
        button.titleLabel?.font = .systemFont(ofSize: 20, weight: .bold)
        button.addTarget(context.coordinator, action: #selector(Coordinator.didTapButton), for: .touchUpInside)

        firstVC.view.addSubview(button)
        button.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            button.centerXAnchor.constraint(equalTo: firstVC.view.centerXAnchor),
            button.centerYAnchor.constraint(equalTo: firstVC.view.centerYAnchor)
        ])
        

        let navVC = UINavigationController(rootViewController: firstVC)
        navVC.navigationBar.isTranslucent = false
        navVC.edgesForExtendedLayout = [.all]
        
        context.coordinator.navigationController = navVC
        
        return navVC
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) { }

    class Coordinator: NSObject {
        let parent: SomeSheetContent
        weak var navigationController: UINavigationController?

        init(_ parent: SomeSheetContent) {
            self.parent = parent
        }

        @objc func didTapButton() {
            let secondVC = UIViewController()
            secondVC.view.backgroundColor = .orange
            secondVC.title = "Second VC"
            secondVC.edgesForExtendedLayout = [.all]
            secondVC.extendedLayoutIncludesOpaqueBars = true

            navigationController?.pushViewController(secondVC, animated: true)
        }
    }
}
  • 1 respostas
  • 31 Views
Martin Hope
Andrei Herford
Asked: 2025-02-26 16:15:01 +0800 CST

Como funcionam os modificadores de visualização como .font (que parecem alterar propriedades internas)?

  • 6

Ainda estou com dificuldade para entender como os modificadores de visualização funcionam no SwiftUI.

Até onde eu sei, os modificadores não alteram diretamente a visualização correspondente, mas, em vez disso, incorporam a visualização em uma nova visualização que aplica as alterações desejadas. Por exemplo, Text(...).padding()NÃO altera algumas propriedades da Textvisualização para criar o preenchimento, mas, em vez disso, incorpora a Textvisualização em uma nova visualização que cuida dos preenchimentos. Portanto, os modificadores não modificam a visualização, mas criam uma nova visualização com as alterações desejadas.

Certo, isso faz todo o sentido.

Mas como funcionam os modificadores, que (parecem) alterar apenas propriedades específicas de uma visualização? Por exemplo, os modificadores .fontou .tint. Embora eu entenda como uma visualização circundante pode alterar propriedades "externas" como plano de fundo, preenchimento, escala, etc., não entendo como o mesmo é possível para propriedades "internas" como a fonte? Como a Textvisualização pode saber, a partir de sua visualização circundante, qual fonte deve usar? Ou como uma visualização circundante poderia recriar a Textvisualização com todas as suas propriedades, mas apenas uma fonte alterada?

Posso criar um personalizado Text("Some example").capitalize("aoe")que crie um texto com todas as mesmas propriedades, como fonte, cor de primeiro plano, etc., mas com "ALGUM Exemplo"?

  • 1 respostas
  • 23 Views
Martin Hope
Andrei Herford
Asked: 2024-12-17 22:32:05 +0800 CST

Quais regras o VStack usa para alocar espaço entre subvisualizações?

  • 7

TL;DR Quais regras o VStack usa para distribuir o espaço disponível entre suas subvisualizações, especialmente quando maxHeight: .infitiyestá envolvido.

Vindo de UIKite LayoutConstraintsainda estou lutando para entender como é SwiftUIo tamanho da visualização.

Depois de ler/assistir a diferentes tutoriais, documentos, etc., entendi que, no final das contas, cada visualização determina seu próprio tamanho. A visualização pai oferece o tamanho disponível, e a criança decide o quão grande ela quer ser. Por exemplo, este vídeo da WWDC mostra isso com bons exemplos.

Entretanto, como isso funciona no seguinte VStack:

VStack(spacing: 0) {
    VStack {
        Text("Top")
           .background(.blue)
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    .background(.red)
    
    VStack {
        Text("Bottom")
           .background(.yellow)
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    .background(.green)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
  • O rootView oferece ao VStack externo o tamanho completo da tela.
  • O VStack externo oferece esse tamanho aos seus filhos e pergunta o quão grande eles querem ser.
  • Os VStacks internos contêm apenas um TextView. Normalmente, eles perguntariam ao textView o quão grande ele quer ser e retornariam esse tamanho como o deles. No entanto, o modificador de frame muda isso para infinit heigt.
  • Ambas as crianças têm altura infinita. Então o VStack externo dá a ambas 50% da altura.

Isso está correto?

Text("Bottom")
   .frame(maxWidth: .infinity, maxHeight: .infinity)
   .background(.yellow)

Agora, o rótulo inferior solicita altura infinita para si mesmo. No entanto, o VStack interno só fornece os 50% disponíveis da altura da tela.

Mas ao adicionar mais Subviews aos VStacks internos, o limite de 50% não é válido:

VStack(spacing: 0) {
    VStack {
        Text("Top1")
        Text("...")
        Text("TopN")
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    .background(.red)
    
    VStack {
        Text("Bottom1")
        Text("...")
        
        // ...
        
        Text("BottomN")
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    .background(.green)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)

Como o tamanho é calculado aqui? Por que o VStack inferior se torna maior que 50% neste caso, mas não antes?

insira a descrição da imagem aqui


Editar:

Estou surpreso que o comportamento da terceira captura de tela não possa ser reproduzido.

Aqui está outra captura de tela mostrando o código completo e o resultado:

insira a descrição da imagem aqui

  • 1 respostas
  • 68 Views
Martin Hope
Andrei Herford
Asked: 2024-11-14 00:05:53 +0800 CST

Como criar séries complexas de animação no SwiftUI

  • 5

Como animações "complexas" podem ser compostas no SwiftUI? Onde complexo significa que a animação completa é composta de múltiplas subanimações.

Exemplo

Estou trabalhando na migração de um projeto existente de UIKitpara SwiftUI. O projeto usa um costume UIViewpara exibir uma barra de progresso que anima as mudanças entre valores positivos e negativos. Valores positivos são mostrados com uma barra verde, valores negativos com uma barra vermelha.

Suponha um maxValuevalor de 100:

  • Um valor de +60 será mostrado como uma barra verde de 60% .
  • Alterar o valor para +20 animará a barra verde para 20% em 1 segundo
  • Alterar o valor para -40 animará a barra verde até 0 em 1/3 de segundo e, em seguida, animará uma barra vermelha perfeitamente de 0 até 40% em 2/3 de segundo. Essa animação completa também leva 1 segundo no total.

Então, o comprimento total da animação é sempre 1 segundo, não importa como o valor muda. Ao mudar de um valor positivo para um negativo (ou vice-versa), a barra encolhe para 0 antes de mudar de cor e ficar mais longa novamente.

Barra de progresso simples

Criar uma barra de progresso simples no SwiftUI não foi grande coisa:

struct SomeProgressBar: View {
    var height: CGFloat = 20
    
    var minValue: Double = 0
    var maxValue: Double = 100
    var currentValue: Double = 20
    
    var body: some View {
        let maxV = max(minValue, maxValue)
        let minV = min(minValue, maxValue)
        
        let currentV = max(min(abs(currentValue - minValue), maxV), minV)
        let isNegative = currentValue < minValue
        
        let progress = (currentV - minV) / (maxV - minV)
        
        Rectangle()
            .fill(.gray)
            .frame(height: height)
            .overlay(alignment: .leading) {
                GeometryReader { geometry in
                    Rectangle()
                        .fill(isNegative ? .red : .green)
                        .frame(width: geometry.size.width * progress)
                }
            }
            .animation(.easeInOut(duration: 0.5), value: progress)
    }
}

struct SomeProgressBarTestView: View {
    @State var value: Double = 40
    
    var body: some View {
        VStack {
            SomeProgressBar(currentValue: value)
            
            Button("Change") {
                value = .random(in: -100...100)
            }
        }
    }
}

Problema

Embora isso funcione bem ao usar apenas valores positivos ou negativos, alternar entre valores positivos e negativos não é animado como pretendido. Por exemplo, alternar entre +x e -x só mudará a cor da barra, mas não animará a barra com isso. Isso não é nenhuma surpresa, pois a largura não muda, é x% antes e depois da mudança de valor. No entanto, o resultado desejado seria animar a largura de x para 0 e de volta para x.

Todas as fontes que encontrei até agora só distinguem animações implícitas e explícitas. Embora isso mude a maneira como a animação é implementada/descrita, não parece influenciar o que a animação pode fazer.

Qual seria a abordagem "correta" para criar a animação "complexa" desejada?

Duas animações diferentes?

Claro que alguém poderia calcular se uma troca entre positivo e negativo ocorreu e disparar duas animações diferentes neste caso com .withAnimation { ... }. Calcular o comprimento da primeira animação e da segunda animação a partir da diferença de valor não seria problema.

No entanto , isso só funcionaria para animações lineares. Ao usar qualquer função de easing como spring, etc., não seria possível obter uma animação contínua com essa abordagem.

Além disso, a barra de progresso é apenas um exemplo. E se ainda mais animação precisasse ser encadeada para obter o resultado desejado.

Existe uma solução para criar animações personalizadas como essas?

  • 1 respostas
  • 38 Views
Martin Hope
Andrei Herford
Asked: 2024-10-11 19:49:21 +0800 CST

Gráfico de barras com dois conjuntos de dados: como posicionar as barras lado a lado em vez de empilhadas?

  • 5

Estou tentando criar um BarChart que mostre dois conjuntos de dados lado a lado: os valores atuais e os valores médios. Não importa o que eu tente, as barras sempre ficam empilhadas.

De acordo com todas as informações que encontrei, isso deveria ser possível usando .foregroundStyle(by: .value(...))and/or .position(by: .value(...)). No entanto, isso não tem efeito aqui.

Para começar, eu ficaria feliz em colocar as barras lado a lado. O objetivo final seria colocar as barras médias ligeiramente deslocadas atrás das barras atuais.

import SwiftUI
import Charts

struct ContentView: View {
    let currentData: [DayData] = (1...15).map { DayData(day: $0, value: Double.random(in: 20...100)) }
    let averageData: [DayData] = (1...15).map { DayData(day: $0, value: Double.random(in: 50...70)) }
    
    var body: some View {
        Chart {
            ForEach(currentData) { day in
                BarMark(
                    x: .value("Day", day.day),
                    y: .value("Current", day.value)
                )
                .foregroundStyle(by: .value("Data Type", "Current"))
                .position(by: .value("Data Type", "Current"))
            }
            
            ForEach(averageData) { day in
                BarMark(
                    x: .value("Day", day.day),
                    y: .value("Average", day.value)
                )
                .foregroundStyle(by: .value("Data Type", "Average"))
                .position(by: .value("Data Type", "Average"))
            }
        }
        .frame(height: 300)
        .padding()
        .chartXAxis {
            AxisMarks(values: currentData.map { $0.day }) { _ in
                AxisTick()
                AxisGridLine()
                AxisValueLabel()
            }
        }
    }
}

// Datensatz für einen Tag
struct DayData: Identifiable {
    let id = UUID()
    let day: Int
    let value: Double
}

#Preview {
    ContentView()
}

insira a descrição da imagem aqui

swiftui
  • 1 respostas
  • 26 Views
Martin Hope
Andrei Herford
Asked: 2024-10-10 18:55:13 +0800 CST

Como definir a posição do AxisValueLabel e dar largura completa ao gráfico?

  • 5

Estou tentando criar um gráfico de linhas SwiftUI. Por padrão, os rótulos y são desenhados ao lado das linhas de grade. Assim, o espaço disponível para o gráfico em si fica menor pela largura do rótulo. Para dar mais espaço ao gráfico, gostaria de mover o rótulo abaixo das linhas de grade.

Embora isso funcione usando AxisValueLabel(anchor: .topLeading), o gráfico não ocupa o espaço agora liberado. Em vez disso, o gráfico mantém a mesma largura que com os rótulos nas posições padrão.

Como mudar isso?

var body: some View {
    Chart {
        ForEach(0..<data.count, id: \.self) { i in
            LineMark(
                x: .value("X", i+1),
                y: .value("Value", data.values[i])
            )
            .foregroundStyle(.red)
            .interpolationMethod(.catmullRom)
            .lineStyle(StrokeStyle(lineWidth: 4))
        }
    }
    .chartYScale(domain: [0, data.maxValue])
    .chartYAxis {
        AxisMarks(position: .leading, values: .automatic(desiredCount: 4)) { value in
            AxisGridLine()
            
            // Default Labels
            // AxisValueLabel()                

            // Hide 0 Label and move others under the line
            if value.index > 0 {
                AxisValueLabel(anchor: .topLeading)
            }
        }
    }
    .frame(height: 300)
    .padding()
}

insira a descrição da imagem aqui

swiftui
  • 1 respostas
  • 25 Views

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve