Swift UI and Canvas Editor - swiftui

On the beta 3 of Xcode 11 the canvas view doesn't work I always have this message "TestPremier.app crashed: communication with the app was interrupted". But in the ContentView.swift I don't have this problem.
I have already tried to create a new app with Swift UI, I already too "Clean Build Folder" or restart my Mac which is running Mac OS 10.15 beta 3.
//
// LongArticleItem.swift
// TestPremier
//
// Created by Mathieu Cloart on 13/07/2019.
// Copyright © 2019 Mathieu Cloart. All rights reserved.
//
import SwiftUI
struct LongArticleItem : View {
var article_data_loading:Article_data_loading
var body: some View {
VStack(alignment: .leading, spacing: 16.0) {
Image(article_data_loading.imageName)
.resizable()
.renderingMode(.original)
.aspectRatio(contentMode: .fill)
.frame(width: 300, height: 170)
.cornerRadius(10)
.shadow(radius: 10)
VStack(alignment: .leading, spacing: 5.0) {
Text(article_data_loading.name)
.color(.primary)
.font(.headline)
Text(article_data_loading.description)
.font(.subheadline)
.color(.secondary)
.multilineTextAlignment(.leading)
.lineLimit(4)
.frame(height: 80)
}
.frame(width: 330)
}
}
}
#if DEBUG
struct LongArticleItem_Previews : PreviewProvider {
static var previews: some View {
LongArticleItem(article_data_loading: articleData[0])
}
}
#endif
I expect to see the result of this in the canvas view but actully I don't even if my build succed

It shows in preview if I comment out this part:
Image(article_data_loading.imageName)
.resizable()
.renderingMode(.original)
.aspectRatio(contentMode: .fill)
.frame(width: 300, height: 170)
.cornerRadius(10)
.shadow(radius: 10)
My guess is that it cannot load an image named by article_data_loading.imageName because it can't find it in the bundle. What does article_data_loading.imageName represent?

Related

SwiftUI - Sheet shows Data half way down the sheet

I am building a small APP where I wanna present a Sheet when a Button is pressed, it all works fine, but when the Sheet is presented the Data starts half way down the Screen rather than at the Top. I am using a ScrollView in the Sheet and above the ScrollView I have a Text and an Image which is Static.
I tried pretty much everything I could find and think of without any success. So now I am hoping someone out there can help me with this.
Here is what it looks like:
Here is the start of the code:
import SwiftUI
struct PopupView: View {
#State var painted = CGFloat(10)
#State var unpainted = CGFloat(1)
#State var sPainted = CGFloat(5)
#State var sUnpainted = CGFloat(6)
var body: some View {
Color.white
VStack(alignment: .leading, spacing: 0) {
HStack {
Text("T'IS IS STATIC HEADER TXT")
.tracking(2)
.foregroundColor(Color.euGray)
.fontWeight(.bold)
.font(.system(size: 12))
.padding(.leading, 100)
.padding(.trailing, 20)
Image("close")
.frame(width: 35, height: 35, alignment: .trailing)
}
}.frame(width: 400, alignment: .topLeading)
ScrollView(showsIndicators: false) {
VStack(alignment: .center) {
Image("qr")
.resizable()
.clipped()
.padding(.top)
.frame(width: 320, height: 320, alignment: .center)
.padding(.top, 5)
Text("JOHN APPLESEED")
.foregroundColor(Color.nameGray)
.fontWeight(.heavy)
.font(Font.custom("Source Sans Pro" ,size: 27))
.padding(.top, 10)
Text("01.01.1976")
.foregroundColor(.gray)
.fontWeight(.regular)
.font(.system(size: 13))
}.frame(width: 320)

iOS 14 Medium Widget Size Background Image Refuses to Fill

For some reason I'm unable to get an image background to aspectFill correctly in XCode Version 12.0, but only on the .systemMedium widget size. It seems to work perfectly on the small and large sizes.
I've got a pretty simple View:
import SwiftUI
#available(iOS 13.0.0, *)
struct Banana: View {
var body: some View {
VStack(alignment: .leading){
Spacer()
Text("Aardvark Exactlywhat")
.font(.largeTitle)
.bold()
.padding(.bottom, 20)
.padding(.leading, 20)
.padding(.trailing, 20)
.minimumScaleFactor(0.5)
.foregroundColor(.white)
.shadow(
color: Color.black,
radius: 1.0,
x: CGFloat(4),
y: CGFloat(4))
}
.edgesIgnoringSafeArea(.all)
.background(
Image("bananas")
.resizable()
.scaledToFill()
).edgesIgnoringSafeArea(.all)
}
}
#available(iOS 13.0.0, *)
struct Banana_Previews: PreviewProvider {
static var previews: some View {
Banana()
}
}
And a pretty simple widget:
struct fruitWidgetEntryView : View {
var entry: Provider.Entry
var body: some View {
Banana()
}
}
#main
struct fruitWidget: Widget {
let kind: String = "fruitWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
fruitWidgetEntryView(entry: entry)
}
.configurationDisplayName("fruit Widget")
.description("Enhance your day with delicious fruit.")
.supportedFamilies([.systemSmall, .systemMedium, .systemLarge])
}
}
struct fruitWidget_Previews: PreviewProvider {
static var previews: some View {
Group{
fruitWidgetEntryView(entry: SimpleEntry(date: Date()))
.previewContext(
WidgetPreviewContext(family: .systemSmall))
fruitWidgetEntryView(entry: SimpleEntry(date: Date()))
.previewContext(
WidgetPreviewContext(family: .systemMedium))
fruitWidgetEntryView(entry: SimpleEntry(date: Date()))
.previewContext(
WidgetPreviewContext(family: .systemLarge))
}
}
}
I've tried changing the aspect ratio, using GeometryReader and frame(), and a dozen other variations. Regardless of what I try, I get white space on the left and right in the medium widget. It only works for the large and small size. See image:
Here is fixed variant - as image in the background you have to expand VStack to full screen.
Note: edgesIgnoringSafeArea allows to go beyond safe area when content is wider, but not make content wide.
var body: some View {
VStack(alignment: .leading){
Spacer()
Text("Aardvark Exactlywhat")
.font(.largeTitle)
.bold()
.padding(.bottom, 20)
.padding(.leading, 20)
.padding(.trailing, 20)
.minimumScaleFactor(0.5)
.foregroundColor(.white)
.shadow(
color: Color.black,
radius: 1.0,
x: CGFloat(4),
y: CGFloat(4))
}
.frame(maxWidth: .infinity, maxHeight: .infinity) // << this one !!
.edgesIgnoringSafeArea(.all)
.background(
Image("plant")
.resizable()
.scaledToFill()
)
}

Clipped not actually clips the Image in SwiftUI

I am trying to clip the image and as we see the UI it looks fine but actually it doesn't clip the image which causes other UI elements to unresponsive.
Here the code I am using.
struct ImageContentView: View {
var urls:[String] = [
"https://lh3.googleusercontent.com/proxy/80im-IBfLODpLDj8d02uEpSVIhqdjen6H6CeFwgRBxeua-Dgw0R3WONFj1Gk8CwB_MufmC9rQ8qHjyWMejwFcJ1PA2s8AAu5WVsmJA=s0-d",
"https://wallpaperaccess.com/full/530919.jpg"
]
var body: some View {
ScrollView{
VStack{
Button(action: {
}, label: {
Text("Hello")
})
VStack(spacing: 20.0) {
ForEach(self.urls, id:\.self) { url in
WebImage(url: URL.init(string: url)!)
.resizable()
.aspectRatio(contentMode: ContentMode.fill)
.frame(height: UIScreen.main.bounds.size.width * 0.5)
.clipped()
.cornerRadius(10.0)
.shadow(color: Color.red, radius: 10.0, x: 0, y: 0)
}
}.padding()
}
}
}
}
Here is fixed part (tested with Xcode 12 / iOS 14)
VStack(spacing: 20.0) {
ForEach(self.urls, id:\.self) { url in
WebImage(url: URL.init(string: url)!)
.resizable()
.aspectRatio(contentMode: ContentMode.fill)
.frame(height: UIScreen.main.bounds.size.width * 0.5)
.clipped()
.cornerRadius(10.0)
.shadow(color: Color.red, radius: 10.0, x: 0, y: 0)
}.contentShape(Rectangle()) // << here !!
}.padding()
Note: I don't know what is your WebImage but with Image and local images it was reproduced as well, so fix was tested.
iOS 13 and +
An other solution is combine compositingGroup and clipped:
That wraps this view in a compositing group and clips.
Note: Respect this order compositingGroup and clipped
Image(..)
.compositingGroup()
.clipped()
I have tried for the above methods but still not working.
Here is another solution for someone who have the same struggle, maybe this can help you :) This line is to disable the tap gesture of the image.
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 100, height: 100)
.contentShape(RoundedRectangle(cornerRadius: 8))
.allowsHitTesting(false) // <- this is the line

swiftui edgesIgnoreSafeArea only showing on canvas and not working on actual device

Im using .edgesIgnoringSafeArea(.top) to ignore the safe area on the top. this seems to work, and show the image going over the safe area on the top as expected on the canvas. But when I run this on a iPhone 11 plus simulator or iPhone x device (i also tested on other devices on the simulator) it doesn't seem to ignore the edges.
I have tried excluding:
.navigationBarTitle("")
.navigationBarBackButtonHidden(true)
But I need the above so I can use a custom back button.
var body: some View {
VStack (alignment: .leading ) {
Image("user1")
.resizable()
.frame(width: (UIScreen.main.bounds.width), height: ((UIScreen.main.bounds.height) / 2) + 50)
ScrollView {
HStack {
Text("\(userData.username), 30")
.fontWeight(.semibold)
.font(.system(.largeTitle, design: .rounded))
.padding([.leading,.top])
Spacer()
Image(systemName: "paperplane")
.aspectRatio(contentMode: .fill)
.frame(width: 65, height: 65)
.background(Color("message-background"))
.foregroundColor(.white)
.cornerRadius(25)
.font(.system(size: 25))
.padding(.top)
}.padding(.trailing)
HStack {
Text("Singer, London")
.fontWeight(.light)
.padding([.leading])
Spacer()
}
HStack {
Text("all the bio info will go there all the bio info will go thereall the bio info will go thereall the bio info will go there all the bio info will go there.")
.fontWeight(.light)
.padding([.leading])
.padding(.top)
.frame(width: (UIScreen.main.bounds.width - 20))
Spacer()
}.padding(.bottom,50)
}
}.edgesIgnoringSafeArea(.top)
.navigationBarTitle("")
.navigationBarBackButtonHidden(true)
.navigationBarItems(leading: Button(action: {
self.presentationMode.wrappedValue.dismiss()
}){
Image(systemName: "arrow.left")
.aspectRatio(contentMode: .fill)
.frame(width: 40, height: 40)
.background(Color("message-background"))
.foregroundColor(.white)
.cornerRadius(15)
.font(.system(size: 15))
.padding(.top,20)
})
}
Your code works for me on the simulator as expected. I just added the Text "This works" to demonstrate it:
So your problem must be somewhere outside the code which you presented in your question.

how to strech image on one side in swiftUI, like a .9 file in Android?

i have an image that i want to strech only it's height to fit different content, how do i do that in swiftUI? right now it looks like this
struct ContentView: View {
var body: some View {
VStack {
HStack {
VStack(alignment: .leading, spacing: 130) {
Text("Title")
.font(.headline)
.foregroundColor(.primary)
Text("text")
.font(.subheadline)
.foregroundColor(.secondary)
Text("padding")
}
.padding(.vertical)
Spacer()
Image("rightTag")
.resizable(capInsets: .init(top: 0, leading: 0, bottom: 0, trailing: 0), resizingMode: .stretch)
.aspectRatio(contentMode: .fit)
.frame(maxWidth: 20)
}
.frame(maxWidth: screen.width - 60)
.padding(.leading)
.background(.white)
.cornerRadius(20)
}
}
}
how can i stretch its height to fit this outer frame? ragular resizable and stuff can't get it done.
any helped would be wonderful! Thanks!
sry i didn't make myself clear earllier.
Here is possible approach. However as I see now you'd rather need to stretch not the entire original image, but only middle of it, so in real project it would be needed to make your image tri-part and apply below stretching approach only to middle (square) part.
Approach uses asynchronous state update, so works in Live Preview / Simulator / RealDevice. (Tested with Xcode 11.2 / iOS 13.2)
struct ContentView: View {
#State private var textHeigh: CGFloat = .zero
var body: some View {
VStack {
HStack(alignment: .top) {
VStack(alignment: .leading, spacing: 130) {
Text("Title")
.font(.headline)
.foregroundColor(.primary)
Text("text")
.font(.subheadline)
.foregroundColor(.secondary)
Text("padding")
}
.padding(.vertical)
.alignmentGuide(.top, computeValue: { d in
DispatchQueue.main.async {
self.textHeigh = d.height // !! detectable height of left side text
}
return d[.top]
})
Spacer()
Image("rightTag")
.resizable()
.frame(maxWidth: 20, maxHeight: max(60, textHeigh)) // 60 just for default
}
.frame(maxWidth: screen.width - 60)
.padding(.leading)
.background(Color.white)
}
}
}