I have a custom UISlider, but there is a side of the slider which is not rounded
Here my custom view:
class PrimarySliderView: UISlider {
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
override func trackRect(forBounds bounds: CGRect) -> CGRect {
return CGRect(origin: bounds.origin, size: CGSize(width: bounds.width, height: 6))
}
func setup() {
tintColor = .cornFlowerBlue
}
How to round the right side also?
EDIT
The slider is cutted because my application is RTL, when I change to LTR this display correctly but not in RTL, how to resolve this problem?
In My AppDelegate I force RTL:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
UIView.appearance().semanticContentAttribute = .forceRightToLeft
return true
}
try this one
if(UIApplication.sharedApplication().userInterfaceLayoutDirection == UIUserInterfaceLayoutDirection.RightToLeft)
{
uiSlider.transform = CGAffineTransformMakeScale(-1.0, 1.0);
}
Here is a solution/workaround and it works with iOS 14 based on this answer . Also, it is tweaked to solve blurry edges.
if UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft {
setMinimumTrackImage(getImageWithColor(color: .blue, size: frame.size).resizableImage(withCapInsets: UIEdgeInsets(top: 3, left: 3, bottom: 3, right: 3), resizingMode: .stretch), for: .normal)
}
And here is the implementation of getImageWithColor:
private func getImageWithColor(color: UIColor, size: CGSize) -> UIImage {
let layer: CALayer = CALayer()
layer.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)
layer.masksToBounds = true
layer.cornerRadius = 3
layer.backgroundColor = color.cgColor
UIGraphicsBeginImageContextWithOptions(size, false, 0)
layer.render(in: UIGraphicsGetCurrentContext()!)
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
NOTE: Don't forget to change cornerRadius and UIEdgeInsets to suit your needs.
Before applying the fix:
After applying the fix:
iOS14+ version of Jawad's answer
final class RoundedSlider: UISlider {
override func layoutSubviews() {
super.layoutSubviews()
if #available(iOS 14.0, *) {
if let layers = layer.sublayers?.first?.sublayers, layers.count > 0, let layer = layers[1] {
layer.cornerRadius = layer.bounds.height / 2
}
} else {
if let layers = layer.sublayers, layers.count > 0, let layer = layers[1] {
layer.cornerRadius = layer.bounds.height / 2
}
}
}
}
For SwiftUI
The problem occurs, as mentioned in the question when forcing the environment to be RTL. like so .environment(\.layoutDirection, .rightToLeft)
I found a simple solution that works for me.
Just use a rotation effect like so: .rotationEffect(Angle(degrees: 180))
on the slider and it will look as if it's RTL.
This will just rotate the slider 180 degrees
Note
if you would like to add some padding make sure to put it after this modifier so it will make sense or else you will have to enter the opposite edge. (for example .bottom
instead of .top
)
This will apply the padding to the top
Slider(value: $progress)
.rotationEffect(Angle(degrees: 180))
.padding(.top, 20) // After rotating
This will apply the padding to the bottom
Slider(value: $progress)
.padding(.top, 20) // before
.rotationEffect(Angle(degrees: 180))
Hope this helps:)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.