Изображение не заполняет весь виджетIOS

Программируем под IOS
Ответить
Anonymous
 Изображение не заполняет весь виджет

Сообщение Anonymous »

Я пытаюсь создать для своего приложения виджет, показывающий обратный отсчет. На заднем плане должно быть изображение, выбранное пользователем. В виджете все работает нормально, за исключением того, что изображение не заполняет весь виджет. Первоначально я думал, что ZStack занимает ровно столько места, сколько VStack с необходимым текстом, но я попытался прокомментировать VStack, и вокруг него все еще есть место.

Я пытался спросить ChatGPT, Claude и Gemini, но все, что они мне сказали, это добавить .scaledToFill(), .frame(maxWidth: .infinity, maxHeight: .infinity) или .ignoresSafeArea(), но они, похоже, не работают.

Если я удалю .resizable(), изображение станет намного больше, чем виджет.

У меня есть такой код:

Код: Выделить всё

struct SimpleEntry: TimelineEntry {
let date: Date
let configuration: ConfigurationAppIntent
}

let backgroundGradient = LinearGradient(
colors: [Color.red, Color.blue],
startPoint: .top, endPoint: .bottom)

struct CountdownsEntryView : View {
var entry: Provider.Entry

func daysLeftText(days_left: Int) -> String {
var days_left_text: String = "\(days_left) days left"

if days_left == 1 {
days_left_text = "\(days_left) day left"
}
else if days_left == 0 {
days_left_text = "Today!"
}
else if days_left < 0 {
days_left_text = "\(abs(days_left)) days ago"
}

return days_left_text
}

var body: some View {
ZStack {
// Background image
if let widgetImg = entry.configuration.countdown?.image,
let uiImg = UIImage(data: widgetImg) {
Image(uiImage: uiImg)
.resizable()
.scaledToFill()
} else {
// Fallback gradient if no image
LinearGradient(
colors: [Color.purple, Color.blue],
startPoint: .top,
endPoint: .bottom
)
}

// Text overlay
VStack(spacing: 30) {
Text(entry.configuration.countdown?.title ?? "Default")
.foregroundStyle(.white)
.font(.largeTitle)
.minimumScaleFactor(0.01)
.lineLimit(1)
.shadow(
color: Color.primary.opacity(0.5), /// shadow color
radius: 3, /// shadow radius
x: 0, /// x offset
y: 2 /// y offset
)

Text(daysLeftText(days_left: daysLeft(date: entry.configuration.countdown?.date ?? Date())))
.foregroundStyle(.white)
.font(.title)
.minimumScaleFactor(0.01)
.lineLimit(1)
.shadow(
color: Color.primary.opacity(0.5), /// shadow color
radius: 3, /// shadow radius
x: 0, /// x offset
y: 2 /// y offset
)
}
.padding()
}
}
}

struct Countdowns: Widget {
let kind: String = "Countdowns"

var body: some WidgetConfiguration {
AppIntentConfiguration(kind: kind, intent: ConfigurationAppIntent.self, provider: Provider()) { entry in
CountdownsEntryView(entry: entry)
.containerBackground(.fill, for: .widget)
//                .background(backgroundGradient)
}
}
}
При добавлении изображения в приложение я его обрабатываю следующим образом:

Код: Выделить всё

extension UIImage {
func croppedToSquare() ->  UIImage {
// If image is already square, return as-is
if size.width == size.height {
return self
}

// Determine the side length (use the smaller dimension)
let sideLength = min(size.width, size.height)

// Calculate the crop rectangle (centered)
let xOffset = (size.width - sideLength) / 2
let yOffset = (size.height - sideLength) / 2
let cropRect = CGRect(x: xOffset, y: yOffset, width: sideLength, height: sideLength)

// Crop the image
guard let cgImage = self.cgImage,
let croppedCGImage = cgImage.cropping(to: cropRect) else {
return self
}

return UIImage(cgImage: croppedCGImage, scale: self.scale, orientation: self.imageOrientation)
}

func resizedForWidget(maxWidth: CGFloat = 400) -> UIImage {
// First crop to square
let squareImage = croppedToSquare()

// If already small enough, return as-is
if squareImage.size.width  UIImage {
// Resize to maximum 300px for widgets (more conservative)
let resized = resizedForWidget(maxWidth: 300)

// Convert to JPEG and back to reduce file size
guard let jpegData = resized.jpegData(compressionQuality: 0.8),
let compressedImage = UIImage(data: jpegData) else {
return resized
}

return compressedImage
}
}
А вот как это выглядит в виджете:

Изображение
Я что-то упустил? Может ли кто-нибудь помочь мне с этим?
Спасибо.

Подробнее здесь: https://stackoverflow.com/questions/797 ... ire-widget
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»