How do I apply a linear gradient with a custom class that I made on a shape? For some reason it is not working for me. The foregroundColor is not working for me.
RoundedRectangle(cornerRadius: 30)
.frame(width: geometry.size.width * 1.01, height:geometry.size.height * 0.23)
.rotationEffect(.degrees(12), anchor: .center)
.foregroundColor(LinearGradient (gradient: Gradient(colors:[Color(ColorsSaved.gitLabDark),Color(ColorsSaved.gitLabLight)]),startPoint: .leading,endPoint: .trailing))
I created my CustomClass in a Swift file. Please see code below for that.
import Foundation
import UIKit
struct ColorsSaved {
static let gitLabDark = UIColor( red: 0.12, green: 0.08, blue: 0.22, alpha: 1.0)
static let gitLabLight = UIColor( red: 0.26, green: 0.2, blue: 0.44, alpha: 1.0)
static let neonGreen = UIColor(red: 0.497, green: 0.738, blue: 0.35, alpha: 1)
static let darkGreenTorquise = UIColor(red: 0.242, green: 0.683, blue: 0.577, alpha: 1)
static let brightOrange = UIColor(red: 0.917, green: 0.469, blue: 0.218, alpha: 1)
If I correctly understood your intention, I would go with the following approach.
Result demo:
Code:
GeometryReader { geometry in
LinearGradient(gradient:
Gradient(colors:
[Color(ColorsSaved.gitLabDark), Color(ColorsSaved.gitLabLight)]),
startPoint: .leading, endPoint: .trailing)
.frame(width: geometry.size.width * 1.01, height:geometry.size.height * 0.23)
.mask(RoundedRectangle(cornerRadius: 30))
.rotationEffect(.degrees(12), anchor: .center)
}
Gradients in SwiftUI are supposed to be added with the help of ZStack. As you haven't added much code in your question I made my assumptions. Try this in your custom view:
struct WelcomeView: View {
var body: some View {
ZStack {
LinearGradient(gradient: Gradient(colors: [.pink, .purple]), startPoint: .leading, endPoint: .trailing)
// here goes your other view component
Text("Welcome, John")
}
}
}
Related
I’m new at SwiftUI and I’ve a doubt. I wonder if anyone can help me.
I’ve a screen with two exact buttons (except for the text that they display and the view which they lead to). When they are tapped, each button leads the user to a new given view.
The code is this:
HStack {
NavigationLink(destination: PlayView()) {
ButtonTextView(buttonText: "Play")
}
.frame(width: 120, height: 40, alignment: .center)
.background(Color(red: 242/255, green: 242/255, blue: 242/255, opacity: 1))
.cornerRadius(10.0)
Spacer()
NavigationLink(destination: RankingView()) {
ButtonTextView(buttonText: "Ranking")
}
.frame(width: 120, height: 40, alignment: .center)
.background(Color(red: 242/255, green: 242/255, blue: 242/255, opacity: 1))
.cornerRadius(10.0)
}
And I want to be able to do something like this:
HStack {
ButtonView(buttonIdentifier: "Play")
Spacer()
ButtonView(buttonIdentifier: "Ranking")
}
Where ButtonView is defined like so:
NavigationLink(destination: PlayView()) {
ButtonTextView(buttonText: "Play")
}
.frame(width: 120, height: 40, alignment: .center)
.background(Color(red: 242/255, green: 242/255, blue: 242/255, opacity: 1))
.cornerRadius(10.0)
So, basically, I don’t repeat code and have a much more readable file.
The problem comes when I’ve to define the destination of the NavigationLink. There is some way I can set the destination to be a variable and pass it when I call ButtonView()? So that if the buttonIdentifier is "Play", destination is PlayView() (like above) and if is "Ranking", then is RankingView().
I hope I’ve been able to explain my problem clearly (i’m not a native speaker…)
Any help is appreciated. Thanks a lot :)!
struct ButtonView<Destination>: View where Destination : View {
let buttonText: String
let destination: Destination
init(buttonText: String, #ViewBuilder destination: #escaping () -> Destination) {
self.buttonText = buttonText
self.destination = destination()
}
var body: some View {
NavigationLink(destination: destination) {
Text(buttonText)
}
.frame(width: 120, height: 40, alignment: .center)
.background(Color(red: 242/255, green: 242/255, blue: 242/255, opacity: 1))
.cornerRadius(10.0)
}
}
Use like:
ButtonView(buttonText: "Play") {
PlayView()
}
I'm converting my project to SwiftUI and I use a background with gradient. I can't figure out how to convert the below to a SwiftUI view:
let layer = CAGradientLayer()
layer.colors = [
UIColor(red: 0.165, green: 0.224, blue: 0.314, alpha: 1).cgColor,
UIColor(red: 0.112, green: 0.17, blue: 0.26, alpha: 1).cgColor]
layer.locations = [0.45, 1]
layer.startPoint = CGPoint(x: 0.25, y: 0.5)
layer.endPoint = CGPoint(x: 0.75, y: 0.5)
layer.transform = CATransform3DMakeAffineTransform(CGAffineTransform(a: 0, b: 0.46, c: -0.46, d: 0, tx: 0.73, ty: 0.68))
layer.bounds = view.bounds.insetBy(dx: -0.5*view.bounds.size.width, dy: -0.5*view.bounds.size.height)
layer.position = view.center
view.layer.addSublayer(layer)
I tried the below, but the results are not the same:
LinearGradient(gradient: Gradient(colors: [Color("BackgroundNEWTop"), Color("BackgroundNEWBottom")]), startPoint: .top, endPoint: .bottom))
After I tested your UIKit code, this is the closest one I replicated in SwiftUI. I included the result image here, but you should try this code yourself first because the online image may look slightly different.
Sample Code and Image are below:
struct SampleView: View {
let color1 = Color.init(red: 0.112, green: 0.17, blue: 0.26)
let color2 = Color.init(red: 0.165, green: 0.224, blue: 0.314)
var body: some View {
ZStack {
LinearGradient(colors: [color1, color2],
startPoint: UnitPoint(x: 0.75, y: 0.5),
endPoint: UnitPoint(x: 0.25, y: 0.5))
}
}
}
Currently, my code uses a series of switch result cases that asks questions and presents different answer choices. For example, when the user clicks Evening, the code will present a new question with the answer choices being "Sweet" and "Savory". How can I put a cool transition where the "Morning" and "Evening" choices turn into the "Sweet" and "Savory" choices? Open to any transitions that you'd recommend.
var body: some View {
let cardWidth = 300
let cardWidthValue = CGFloat(cardWidth)
let cardHeight = 300
let cardHeightValue = CGFloat(cardHeight)
VStack {
ZStack {
Rectangle()
.fill(Color(red: 0.0, green: 0.5, blue: 1.0, opacity: 0.4))
.frame(width: 350, height: 250)
.cornerRadius(20)
.shadow(color: .gray, radius: 20)
switch result {
case "Start":
VStack{
Text("What time is it?")
.padding()
.foregroundColor(Color.white)
.font(.system(size: 30.0, weight: .bold))
HStack {
Button {
result = "M"
} label: {
Text("Morning🌥")
.foregroundColor(Color.white)
.frame(width: 165, height: 100)
.background(Color(red: 0.0, green: 0.0, blue: 1.0, opacity: 1.0))
.cornerRadius(10)
}
Button {
result = "E"
} label: {
Text("Evening☀️")
.foregroundColor(Color.white)
.frame(width: 165, height: 100)
.background(Color(red: 0.0, green: 0.0, blue: 1.0, opacity: 1.0))
.cornerRadius(10)
}
}
}
case "E":
VStack{
Text("Sweet or Savory?")
.padding()
.foregroundColor(Color.white)
.font(.system(size: 30.0, weight: .bold))
HStack {
Button {
result = "EveningSweet"
} label: {
Text("Sweet🍦")
}
.foregroundColor(Color.white)
.frame(width: 165, height: 100)
.background(Color(red: 0.0, green: 0.0, blue: 1.0, opacity: 1.0))
.cornerRadius(10)
Button {
result = "EveningSavory"
} label: {
Text("Savory🧂")
}
.foregroundColor(Color.white)
.frame(width: 165, height: 100)
.background(Color(red: 0.0, green: 0.0, blue: 1.0, opacity: 1.0))
.cornerRadius(10)
}
}
Using withAnimation{} to animate your event.
Let's say you want to animate views after you click on Evening:
Button {
withAnimation { //here
result = "E"
}
} label: {
Text("Evening☀️")
.foregroundColor(Color.white)
.frame(width: 165, height: 100)
.background(Color(red: 0.0, green: 0.0, blue: 1.0, opacity: 1.0))
.cornerRadius(10)
}
This mean that all views that are related to this event of result = "E" shall be animated. The default transition of all animation is .opacity.
After trying the first case, if you want to change transition type, use .transition()
case "E":
VStack {
}.transition(.slide)
You will see a different animation from the first time that you did not set transition equals to slide.
I would recommend you try the first option without .slide first to see the difference.
i have this card thing in the picture to build, here're the code:
struct ArticleCard: View {
var article: Article
var body: some View {
ZStack {
Color.white
.border(Color(red: 0, green: 0, blue: 0, opacity: 0.2))
.shadow(color: Color(red: 0, green: 0, blue: 0, opacity: 0.2), radius: 0.0, x: 5, y: 5)
VStack{
Text(article.title)
.padding(.top, 5)
.padding(.leading)
.padding(.trailing)
.font(.title2)
Image(article.coverUrl).resizable()
.frame(height: 200)
.padding(.leading)
.padding(.trailing)
Text(article.title)
.padding(.leading)
.padding(.trailing)
.padding(.bottom)
}
}
}
}
in the ZStack i put a Color.white there as a background of the card, and give this color view a shadow, but the color seems to be transparent, therefor i got unwanted lines on the top and the left inside the borders, how do i get rid of them?
You are using border and shadow in wrong place, try this:
PS: there is no reason of using Color(red: 0, green: 0, blue: 0, opacity: 0.2) you can use this: Color.black.opacity(0.2)
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack {
Color.white
VStack {
Text("article.title")
.padding()
Image(systemName: "star")
.resizable()
.scaledToFit()
Text("article.title")
.padding()
}
}
.frame(width: 300, height: 300, alignment: .center)
.border(Color(red: 0, green: 0, blue: 0, opacity: 0.2))
.compositingGroup()
.shadow(color: Color(red: 0, green: 0, blue: 0, opacity: 0.2), radius: 0.0, x: 5, y: 5)
}
}
I refactored your code for better and less code as possible you can use Image instead of Text in your App.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Text("your custom Text")
.padding()
Text("🥩")
.font(Font.system(size: 150))
Text("your custom Text")
.padding()
}
.frame(width: 300, height: 300, alignment: .center)
.background(Color.white)
.border(Color.black.opacity(0.2))
.compositingGroup()
.shadow(color: Color.black.opacity(0.2), radius: 0.0, x: 5, y: 5)
}
}
I am looking to have my scroll view fade out near the edge. I have implemented a mask, which almost achieves what I want. However, the scrolling stops working and the mask blacks out the rectangles (which should instead have images).
I have seen another post that overlays the background colour overtop of the view to create something that looks like a fade out, but my background is a gradient so it wouldn't work.
var body: some View {
ZStack {
LinearGradient(
gradient: Gradient(colors: [Color(#colorLiteral(red: 0.1333333333, green: 0.7098039216, blue: 0.4509803922, alpha: 1)), Color(#colorLiteral(red: 0.1607843137, green: 0.6705882353, blue: 0.8862745098, alpha: 1))]),
startPoint: .top, endPoint: .bottom)
.ignoresSafeArea()
LinearGradient(gradient: Gradient(colors: [.clear, .black, .clear]), startPoint: .leading, endPoint: .trailing)
.mask(ScrollingRectangles())
}
}
Here is the result of the above code:
Below is an example I threw together to illustrate what I'm trying to achieve.
You can check out this: https://designcode.io/swiftui-handbook-mask-and-transparency
OR
You can use masking to implement the transparency effect
ZStack {
// Your View here....
}
.mask(LinearGradient(gradient: Gradient(colors: [.black, .black, .black, .clear]), startPoint: .bottom, endPoint: .top))