despite my best efforts, I am failing on the code for the fade-in timing of my frame. for some reason that I cant understand, the withDuration is not fading at all.
if someone has a moment to review my code I would v much appreciate the help...
import UIKit
import PlaygroundSupport
let view = UIView(frame: CGRect(x: 128, y: 128, width: 256, height: 256))
view.backgroundColor = .red
UIView.animate(withDuration: 3) {
view.alpha = 1
}
let containerView = UIView(frame: CGRect(x: 0, y: 0, width: 512, height:
512))
containerView.backgroundColor = .white
PlaygroundPage.current.liveView = containerView
containerView.addSubview(view)
Problem 1: view.alpha is already 1 so there is nothing to animate.
Problem 2: Order matters. Things happen in the order you command them. That order must be coherent.
So:
let containerView = UIView(frame: CGRect(x: 0, y: 0, width: 512, height: 512))
containerView.backgroundColor = .white
PlaygroundPage.current.liveView = containerView
let view = UIView(frame: CGRect(x: 128, y: 128, width: 256, height: 256))
view.alpha = 0
view.backgroundColor = .red
containerView.addSubview(view)
UIView.animate(withDuration: 3) {
view.alpha = 1
}
Related
I have migrated my app from Swift 3.1 to Swift 4.0 (Xcode 8.3.3 to Xcode 9.0) and some part of my interface is broken now. Navigation Bar of Navigation controller is complete mess. Please, look at screenshot:
There are 3 elements:
left Netfnet logo (image)
right Signal strength (image)
right QR Code button
As you can see, two images are too big and not in center and button was deformed (it should be perfect square, all images too).
There is code which generated navigation controller:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
settings()
}
func settings() {
let color = UIColor(red: 81 / 255, green: 155 / 255, blue: 22 / 255, alpha: 1.0)
self.navigationController?.navigationBar.barTintColor = color
let logoImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 35, height: 35))
logoImageView.contentMode = .scaleAspectFit
let logo = UIImage(named: "littleLogoImage")
logoImageView.image = logo
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: logoImageView)
let signalStengthImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 35, height: 35))
signalStengthImageView.contentMode = .scaleAspectFit
signalStengthImageView.image = UIImage(named: "signalStrength4")
let signalStengthImageItem = UIBarButtonItem(customView: signalStengthImageView)
let button = UIButton(type: .custom)
button.setImage(UIImage(named: "qrCodeButton"), for: .normal)
button.frame = CGRect(x: 0, y: 0, width: 35, height: 35)
let qrCodeButtonItem = UIBarButtonItem(customView: button)
navigationItem.rightBarButtonItems = [qrCodeButtonItem, signalStengthImageItem] //
}
}
I can decrease resolution of images directly myself, but I just don't get why everting was fine in Swift 3.1 and in Swift 4.0 is broken.
I will be thankful for any help or advice.
You have to add width and height constraints.
Your barImageView and barButton in CustomNavigationController should be like below :
func barImageView(imageName: String) -> UIBarButtonItem {
let imgView = imageView(imageName: imageName)
let widthConstraint = imgView.widthAnchor.constraint(equalToConstant: 35)
let heightConstraint = imgView.heightAnchor.constraint(equalToConstant: 35)
heightConstraint.isActive = true
widthConstraint.isActive = true
return UIBarButtonItem(customView: imgView)
}
func barButton(imageName: String, selector: Selector) -> UIBarButtonItem {
let button = UIButton(type: .custom)
button.setImage(UIImage(named: imageName), for: .normal)
button.frame = CGRect(x: 0, y: 0, width: 35, height: 35)
button.addTarget(self, action: selector, for: .touchUpInside)
let widthConstraint = button.widthAnchor.constraint(equalToConstant: 35)
let heightConstraint = button.heightAnchor.constraint(equalToConstant: 35)
heightConstraint.isActive = true
widthConstraint.isActive = true
return UIBarButtonItem(customView: button)
}
Your signalStengthImageView in LogoWithSignalStrength:
signalStengthImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 35, height: 35))
signalStengthImageView.contentMode = .scaleAspectFit
let widthConstraint = signalStengthImageView.widthAnchor.constraint(equalToConstant: 35)
let heightConstraint = signalStengthImageView.heightAnchor.constraint(equalToConstant: 35)
heightConstraint.isActive = true
widthConstraint.isActive = true
In Xcode 9, Navigation bar items are constraints base, Add this:
if #available(iOS 11.0, *) {
logoImageView.widthAnchor.constraint(equalToConstant: 35).isActive = true
logoImageView.heightAnchor.constraint(equalToConstant: 35).isActive = true
} else {
//set frames
}
I have an animation that deletes a circle in the UI and then recreates it somewhere else, but when I recreate it, it is smaller than what I want. I can't figure out why it is appearing smaller.
let viewsToAnimate = [circleFrame]
UIView.perform(UISystemAnimation.delete, on: viewsToAnimate, options: [], animations: {
}, completion: { finished in
self.circle.removeFromSuperlayer()
self.circleFrame.removeFromSuperview()
self.circleFrame.layer.removeAllAnimations()
self.createCircle()
self.score = self.score + 1
self.scoreLabel.text = "Taps: " + String(self.score)
self.tapsLabel.text = "Taps: " + String(self.initialTaps + self.score)
})
func createCircle() {
let randomX = generateRandomX()
let randomY = generateRandomY()
circleCenter = generateCircleCenter(x: randomX, y: randomY)
circleFrame.frame = CGRect(x: randomX, y: randomY, width: 100, height: 100)
circleFrame.alpha = 1.0
self.view.addSubview(circleFrame)
circle.path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: 100, height: 100), cornerRadius: 50).cgPath
circle.fillColor = UIColor(red: 0, green: greenValue/255, blue: 0.6, alpha: 1.0).cgColor
circle.strokeColor = UIColor(red: 1, green: greenValue/255, blue: 0, alpha: 1.0).cgColor
circle.lineWidth = 0
circleFrame.layer.addSublayer(circle)
}
I have tried removing all the animations among other things but it always appears smaller. Any help on why this happens would be great.
Here is how it looks the first time createCircle() is called.
This is how it looks when it is called from the animation.
I think is enough to set removedOnCompletion to true, so CAAnimation will reset to original size.
Give a try ! :)
I would like to draw the border of a label (UILabel) with three straight sides and a rounded as you can see an example picture: example label.
I use X-Code 7 and Swift 2.1
You can create a shape layer and use it in the label. I tried to get close to the sample in Playground:
import UIKit
import XCPlayground
let label = UILabel(frame: CGRect(x: 50, y: 170/2, width: 100, height: 30))
let rectanglePath = UIBezierPath(roundedRect: CGRectMake(1.5, 1.5, 97, 27), byRoundingCorners: [UIRectCorner.TopRight, UIRectCorner.BottomRight], cornerRadii: CGSizeMake(15, 15))
rectanglePath.closePath()
let color = [#Color(colorLiteralRed: 0.8442155122756958, green: 0.9805876612663269, blue: 0.9611368179321289, alpha: 1)#]
color.setFill()
rectanglePath.fill()
color.setStroke()
rectanglePath.lineWidth = 3
rectanglePath.stroke()
let mask = CAShapeLayer()
mask.path = rectanglePath.CGPath
label.textAlignment = .Center
label.backgroundColor = [#Color(colorLiteralRed: 0.990426778793335, green: 0.5112959146499634, blue: 0.4327127933502197, alpha: 1)#]
label.text = "Welcome...."
label.font = UIFont.systemFontOfSize(10)
label.layer.mask = mask
let view = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
view.backgroundColor = color
view.addSubview(label)
XCPShowView("Label", view: view)
Here is my current code:
var reply = UIBarButtonItem(image: UIImage(named: "reply"), style: UIBarButtonItemStyle.Plain, target: self, action: Selector("reply:"))
self.navigationItem.rightBarButtonItem = reply
The button in the top right corner is always fuzzy. This is a screenshot from an iPhone4s device so it is not a retina-related issue.
I have tried different image sizes ranging from 30x30 to 512x512 and adding the image using customView. These methods have not fixed the issue.
Thanks in advance.
I have solved it using this method:
var replyBtn = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
replyBtn.setImage(UIImage(named: "reply"), forState: UIControlState.Normal)
replyBtn.addTarget(self.navigationController, action: Selector("reply:"), forControlEvents: UIControlEvents.TouchUpInside)
var item = UIBarButtonItem(customView: replyBtn)
self.navigationItem.rightBarButtonItem = item
It displays a very crisp button using the exact same image.
From IOS human interface guide the icon should be 22x22
Take a look at the documentation here:
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/BarIcons.html
Try this:
func createBarButton(image: String, size: CGSize, offset: (x: CGFloat, y: CGFloat) = (0,0), hightlightable: Bool = true, action: Selector) -> UIBarButtonItem {
let btn = UIButton(type: .custom)
let img = UIImage(named: image)
btn.setBackgroundImage(img, for: .normal)
btn.addTarget(self, action: action, for: .touchUpInside)
btn.frame = CGRect(x: offset.x, y: offset.y, width: size.width, height: size.height)
btn.adjustsImageWhenHighlighted = hightlightable
let view = UIView(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height))
// view.bounds = view.bounds.offsetBy(dx: offset.x, dy: offset.y)
view.addSubview(btn)
let barButton = UIBarButtonItem(customView: view)
return barButton
}
self.navigationItem.rightBarButtonItem = createBarButton(image: "YOUR_IMAGE",
size: CGSize(width: 35, height: 35),
offset: (x: -10, y: 0),
action: #selector(showXY))
Been going nuts trying to get a live view of an animation in a Swift Playground like in the WWDC "Swift Playgrounds" video. I tried to do a UIView.animateWithDuration with no luck so I am now trying to do a CABasicaAnimation because this seems to be what was used in the demo. I'be gotten rid of a lot of confusing errors and have imported the proper frameworks but am still having no luck getting my little circle to do anything but sit still in the center of my XCPShowView. Here is my code:
import Foundation
import XCPlayground
import UIKit
import QuartzCore
//Circle Button
class timerButtonGraphics: UIView {
override func drawRect(rect: CGRect) {
let colorGreen = UIColor(red: 0.310, green: 0.725, blue: 0.624, alpha: 1.000)
let colorRed = UIColor(red: 241/255, green: 93/255, blue: 79/255, alpha: 100)
var bounds = self.bounds
var center = CGPoint()
center.x = bounds.origin.x + bounds.size.width / 2
center.y = bounds.origin.y + bounds.size.height / 2
var radius = 61
var path:UIBezierPath = UIBezierPath()
path.addArcWithCenter(center, radius: CGFloat(radius), startAngle: CGFloat(0.0), endAngle: CGFloat(Float(M_PI) * 2.0), clockwise: true)
path.strokeWithBlendMode(kCGBlendModeNormal, alpha: 100)
path.lineWidth = 5
colorGreen.setStroke()
path.stroke()
//Define the animation here
var anim = CABasicAnimation()
anim.keyPath = "scale.x"
anim.fromValue = 1
anim.toValue = 100
anim.delegate = self
self.layer.addAnimation(anim, forKey: nil)
}
}
var test = timerButtonGraphics(frame: CGRect(x: 0, y: 0, width: 400, height: 400))
test.setTranslatesAutoresizingMaskIntoConstraints(true)
XCPShowView("Circle Animation", test)`
The first part of the solution is to enable the Run in Full Simulator option. See this answer for a step-by-step.
The second part of the solution is to contain your animated view in a container view, e.g.:
let container = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 400))
XCPShowView("Circle Animation", container)
let test = timerButtonGraphics(frame: CGRect(x: 198, y: 0, width: 4, height: 400))
container.addSubview(test)
The third part of the solution is to correct your animation. The keyPath should be transform.scale.x instead of scale.x and you need to add a duration, e.g.:
anim.keyPath = "transform.scale.x"
anim.duration = 5
You should then be able to view the animation in your playground.