Any way to get a gif as a background with swiftUI?
I've used a WKWebView to display a gif. The resulting view can be set anywhere. To set it as a background, you'll probably want to resize the contents of the WKWebView according to the contents of the superview.
import SwiftUI
import WebKit
struct HTMLRenderingWebView: UIViewRepresentable {
@Binding var htmlString: String
@Binding var baseURL: URL?
func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView()
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
if self.htmlString != context.coordinator.lastLoadedHTML {
print("Updating HTML")
context.coordinator.lastLoadedHTML = self.htmlString
uiView.loadHTMLString(self.htmlString, baseURL: self.baseURL)
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject {
var parent: HTMLRenderingWebView
var lastLoadedHTML = ""
init(_ parent: HTMLRenderingWebView) {
self.parent = parent
}
}
}
struct HTMLRenderingWebViewExample: View {
@State var htmlString = ""
var body: some View {
VStack {
HTMLRenderingWebView(htmlString: self.$htmlString, baseURL: .constant(nil))
.padding(30).background(Color.gray)
Button("Click this button") {
self.htmlString = "<meta name=\"viewport\" content=\"initial-scale=1.0\" />" +
(self.assetAsString() ?? "image loading failed")
}
}.navigationBarTitle("Example HTML Rendering")
}
func assetAsString() -> String? {
let asset = NSDataAsset(name: "User_OhSqueezy_on_commons_wikimedia_org_Parallax_scrolling_example_scene")
if let data = asset?.data {
let base64string = data.base64EncodedString()
let format = "gif"
return "<img src='data:image/\(format);base64," + base64string + "' height=240 width=360>"
} else {
return nil
}
}
}
I got my animated gif from Wikimedia Commons and dragged it into the Assets.xcassets
in Xcode.
Result:
How can I give a background Image to my View in SwiftUI
You should use ZStack for this work or send the Image to background like in code:
Also I made some code for you to make you free to use that file Image and you get same and much more better result with system shape. you can change the Color, shape, size, number of bubble and every thing . .
with usage of contrast: make the Color like your Color
import SwiftUI
struct ContentView: View {
@State private var email: String = ""
@State private var password: String = ""
@State private var showPassword = false
var body: some View {
return VStack(content: {
Spacer()
.frame(height: 100)
Text("PET SUPPORT")
.font(Font.custom("Permanent Marker", size: 36))
.padding()
Group {
HStack {
Text("EMAIL")
.font(Font.custom("Permanent Marker", size: 18))
.padding(.top, 20)
Spacer()
}
TextField("Email", text: $email)
.autocapitalization(.none)
.disableAutocorrection(true)
.keyboardType(.emailAddress) // <<: Here: A type optimized for multiple email address entry (shows space @ . prominently).
.padding(.top, 20)
Divider()
.foregroundColor(.black)
}
Group {
HStack {
Text("PASSWORD")
.font(Font.custom("Permanent Marker", size: 18))
.padding(.top, 50)
Spacer()
}
ZStack {
if showPassword {
TextField("Password", text: $password)
}
else {
SecureField("Password", text: $password)
}
}
.frame(height: 20)
.overlay(Image(systemName: showPassword ? "eye.slash" : "eye").onTapGesture { showPassword.toggle() }, alignment: .trailing)
.autocapitalization(.none)
.disableAutocorrection(true)
.padding(.top, 20)
Divider()
.foregroundColor(.black)
}
Group {
Button("Sign Up") {}
.padding()
Button("Login") {}
.padding()
}
Spacer()
})
.padding(.horizontal, 30)
.background(bubble, alignment: .topLeading)
.background(bubble.rotationEffect(Angle(degrees: 180)), alignment: .bottomTrailing)
.ignoresSafeArea()
.statusBar(hidden: true)
}
var bubble: some View { // <<: you can put this part out and use update code for this part
Image("UIBubble")
.resizable()
.scaledToFit()
.frame(width: 217, height: 184, alignment: .leading)
}
}
Update: you can replace that file Image with high quality system shape like this code!
var bubble: some View {
ZStack {
Circle()
.fill(Color(UIColor.systemTeal).opacity(0.2)) // <<: Here: opacity = 0.2
.frame(width: 300, height: 300, alignment: .center)
.offset(x: -100, y: -180)
Circle()
.fill(Color(UIColor.systemTeal).opacity(0.2)) // <<: Here: opacity = 0.2
.frame(width: 300, height: 300, alignment: .center)
.offset(x: -180, y: -100)
}
.contrast(3.0) // <<: Here: This make your Color POP out!
}
Update 2: with this down code your Circle/bubble came to live and they move with smooth animation.
@State private var startAnimation: Bool = false
var bubble: some View {
ZStack {
Circle()
.fill(Color(UIColor.systemTeal).opacity(0.2)) // <<: Here: opacity = 0.2
.frame(width: 300, height: 300, alignment: .center)
.offset(x: startAnimation ? -110 : -100, y: startAnimation ? -180 : -150)
Circle()
.fill(Color(UIColor.systemTeal).opacity(0.2)) // <<: Here: opacity = 0.2
.frame(width: 300, height: 300, alignment: .center)
.offset(x: startAnimation ? -180 : -150, y: startAnimation ? -90 : -100)
}
.contrast(3.0) // <<: Here: This make your Color POP out!
.onAppear() { startAnimation = true }
.animation(Animation.easeInOut(duration: 3.0).repeatForever(autoreverses: true))
}
In SwiftUI, how can I add a video on loop as a fullscreen background image?
You can use the AV
family of frameworks and UIViewRepresentable
to do this:
import SwiftUI
import AVKit
struct PlayerView: UIViewRepresentable {
func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<PlayerView>) {
}
func makeUIView(context: Context) -> UIView {
return PlayerUIView(frame: .zero)
}
}
In order for the video to loop I have added an observer and set the actionAtItemEnd
to .none
to support looping.
When the video reaches the end it will execute the playerItemDidReachEnd(...)
method and seek to the beginning of the video and keep looping.
The example points to a remote video URL. If you want to point to a file within your application you can use Bundle.main.url
to do so instead:
if let fileURL = Bundle.main.url(forResource: "IMG_2770", withExtension: "MOV") {
let player = AVPlayer(url: fileURL)
// ...
}
class PlayerUIView: UIView {
private let playerLayer = AVPlayerLayer()
override init(frame: CGRect) {
super.init(frame: frame)
let url = URL(string: "https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8")!
let player = AVPlayer(url: url)
player.actionAtItemEnd = .none
player.play()
playerLayer.player = player
playerLayer.videoGravity = .resizeAspectFill
NotificationCenter.default.addObserver(self,
selector: #selector(playerItemDidReachEnd(notification:)),
name: .AVPlayerItemDidPlayToEndTime,
object: player.currentItem)
layer.addSublayer(playerLayer)
}
@objc func playerItemDidReachEnd(notification: Notification) {
if let playerItem = notification.object as? AVPlayerItem {
playerItem.seek(to: .zero, completionHandler: nil)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
playerLayer.frame = bounds
}
}
struct ContentView: View {
var body: some View {
NavigationView {
ZStack {
PlayerView()
.edgesIgnoringSafeArea(.all)
}
}
}
}
How to make background disappear with animation in SwiftUI?
Assuming you want the color to change only on dark mode/light mode changes:
From my experience programmatically changing color for dark mode/light mode doesnt work well in SwiftUI. You should instead declare your dark-mode-friendly colors in the assets folder and use those colors. You'll also get a little bit of a nice animation for free, when users change from light mode to dark mode.
There are other approaches as well, but i find this approach good enough.
Here's a useful post about how to define dynamic colors and more: https://medium.com/@drevathy/dark-theme-for-ios-13-in-swift-efc62ef6d16e
EDIT: regarding the transition not working, i found a solution in another stackoverflow question.
basically you need to apply a .zIndex([A Sufficient Number Here])
at the end of your view, before you reach the end of the if showContent { }
.
something like:
if showContent {
ZStack {
ContentView(name: "", showAddWindow: false, title: $curLName)
VStack {
HStack {
Button(action: {
withAnimation {
self.showContent.toggle()
}
}) {
Image(systemName: "xmark.circle.fill").font(.title)
Spacer()
}.padding(.leading, 20)
}
Spacer()
}
.padding(.top,15)
}
.background(darkMode ? Color(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)) : Color(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)))
.animation(.default)
.transition(.move(edge: .trailing))
.zIndex(2) // <<------ Note this!
}
SwiftUI, how to make the background color animate multiple times
should cause the button's background color to pop to another color then quickly fade back to the original color.
You need to declare a function for that. Here is a possible approach for it:
struct ContentView: View {
@State var buttonFlash: Bool = false
var body: some View {
Text("Hello")
.font(.system(size: 20))
.frame(width: 100, height: 50)
.foregroundColor(Color.blue)
.background(buttonFlash ? Color.white : Color.red)
.cornerRadius(30)
.onTapGesture {
print("Tapped!")
self.colorChange()
}
}
private func colorChange() {
// first toggle makes it red
self.buttonFlash.toggle()
// wait for 1 second
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1), execute: {
// Back to normal with ease animation
withAnimation(.easeIn){
self.buttonFlash.toggle()
}
})
}
}
It calls the method once tapped. This then triggers the color change and reverses it after 1 second.
Produces this outcome:
Related Topics
How to Display Mtkview with Rgba16Float Mtlpixelformat
Convert Swift Encodable Class Typed as Any to Dictionary
What Does This Mean? Variable Declared Followed by a Block Without Assignment
My Button Is Centered for iPhone 6 and 6 Plus, But Not for iPhone 5
How to Add Characters into Dateformatter
Contacts Not Recognized When Body Is Changed from Circle to Rectangle
Swiftui How to Invoke the Function and Change View from Other Page
Swift Interstitial Making a Banner Ad
Xcode Swift 3: Timer and Segue View Controller Error
Var Declaration with Type VS Without
How to Run the Simulator the Operation Couldn't Be Completed. (Launchserviceserror Error 0.)
Replacing Multiple Different Occurences with Multiple Different Replacements - Swift4.2
Why Does Classa Adopting Protocolb Not Satisfy the Protocolb Requirement
Exc Bad Access After Coding Signing
Cannot Read Property 'Keycode' 'Character' Assertion Failure When Detect Modifier Key + Numeric Key
Swift Uikit Dynamics Add Collision Boundary. After Rotation Does Not Work Correctly