setImage swift position - swift

I’m new in programming with Xcode and Swift and it seems that I do not understand the language correct. I’m trying to create a button which changes the image when clicked and an animated popup of the menu. All works fine as long as I don’t change the image. As soon as I add the toggling of the button-image, the animation doesn’t do what it should do.
I have the impression that some parameters are changed when I use ‘setImage’.
#IBAction func buttonMoreClicked(_ sender: UIButton) {
toggleButton(button: sender, imageOn: UIImage(named: "iconClose.png")!, imageOff: UIImage(named: "iconAdd.png")!)
if (boolFirstClickButtonMore == false) {
boolFirstClickButtonMore = true
self.centerAddEventButton = self.buttonAddEvent.center
self.centerAddGroceryButton = self.buttonAddGrocery.center
self.centerAddTasksButton = self.buttonAddTasks.center
self.righttopAddEventLabel = self.labelAddEvent.frame.origin
self.righttopAddGroceryLabel = self.labelAddGrocery.frame.origin
self.righttopAddTasksLabel = self.labelAddTasks.frame.origin
self.buttonAddEvent.center = self.buttonMore.center
self.buttonAddGrocery.center = sender.center
self.buttonAddTasks.center = sender.center
self.labelAddEvent.frame.origin = self.buttonMore.frame.origin
self.labelAddGrocery.frame.origin = self.buttonMore.frame.origin
self.labelAddTasks.frame.origin = self.buttonMore.frame.origin
}
// If button 'MORE' is set then hide menu buttons
if (boolSetMore) {
boolSetMore = false
sender.layer.backgroundColor = self.colorGreen.cgColor
UIView.animate(withDuration: 0.3, animations: {
self.buttonAddEvent.center = self.buttonMore.center
self.buttonAddGrocery.center = sender.center
self.buttonAddTasks.center = sender.center
self.labelAddEvent.frame.origin = self.buttonMore.frame.origin
self.labelAddGrocery.frame.origin = sender.frame.origin
self.labelAddTasks.frame.origin = sender.frame.origin
self.viewDisable.alpha = 0.0
self.buttonAddEvent.alpha = 0.0
self.buttonAddGrocery.alpha = 0.0
self.buttonAddTasks.alpha = 0.0
self.labelAddEvent.alpha = 0.0
self.labelAddGrocery.alpha = 0.0
self.labelAddTasks.alpha = 0.0
})
}
else {
boolSetMore = true
self.viewDisable.alpha = 0.75
self.buttonMore.layer.backgroundColor = self.colorDarkGreen.cgColor
UIView.animate(withDuration: 0.3, animations: {
self.buttonAddEvent.center = self.centerAddEventButton
self.buttonAddGrocery.center = self.centerAddGroceryButton
self.buttonAddTasks.center = self.centerAddTasksButton
self.labelAddEvent.frame.origin = self.righttopAddEventLabel
self.labelAddGrocery.frame.origin = self.righttopAddGroceryLabel
self.labelAddTasks.frame.origin = self.righttopAddTasksLabel
self.buttonAddEvent.alpha = 1.0
self.buttonAddGrocery.alpha = 1.0
self.buttonAddTasks.alpha = 1.0
self.labelAddEvent.alpha = 1.0
self.labelAddGrocery.alpha = 1.0
self.labelAddTasks.alpha = 1.0
})
}
}
func toggleButton(button: UIButton, imageOn: UIImage, imageOff: UIImage) {
if (button.currentImage == imageOn) {
button.setImage(imageOff, for: .normal )
}
else {
button.setImage(imageOn, for: .normal )
}
}
When clicking on the buttonMore, three buttons and labels appear from the buttonMore. When clicking again, the three buttons and labels should move back to the buttonMore and alpha is set 0 (animated). This works fine but when I add the toggling of the image, the positions of the three buttons changes and the animations disappears. Anybody an idea?

Related

HomeKit Camera Streaming Not Working in Swift

I've tried building a simple HomeKit app to stream video from a HomeKit Camera and while it appears to be working - the stream is not showing on the View Controller. Any help appreciated.
#IBOutlet weak var liveStreamView: HMCameraView!
// var liveStreamView: HMCameraView?
func startCameraStream(for accessory: HMAccessory) {
// Ensure this is a camera accessory
guard let cameraStreamControl = accessory.cameraProfiles?.first?.streamControl else
{ return }
cameraStreamControl.delegate = self
cameraStreamControl.startStream()
let liveStreamView = HMCameraView()
self.view.addSubview(liveStreamView)
self.liveStreamView = liveStreamView
self.liveStreamView.cameraSource = cameraStreamControl.cameraStream
self.liveStreamView?.setNeedsDisplay()
self.view.layoutIfNeeded()
}
extension ViewController: HMCameraStreamControlDelegate {
func cameraStreamControlDidStartStream(_ cameraStreamControl: HMCameraStreamControl) {
liveStreamView?.cameraSource = cameraStreamControl.cameraStream
}
}
So silly. I forgot to define the liveStreamView attributes including the frame. See below where I set the background color, alpha, tag, etc:
func startCameraStream( for accessory: HMAccessory) {
// Ensure this is a camera accessory
guard let cameraStreamControl = accessory.cameraProfiles?.first?.streamControl else
{ return }
cameraStreamControl.delegate = self
cameraStreamControl.startStream ( )
let liveStreamView = HMCameraView(frame: CGRect(x: 0, y: 0, width: 320, height: 568))
liveStreamView.backgroundColor = .clear
liveStreamView.alpha = 0.5
liveStreamView.tag = 100
liveStreamView.isUserInteractionEnabled = true
self.view.addSubview(liveStreamView)
self.liveStreamView = liveStreamView
}

Swift macOS animating two NSTextViews

I want to animate two textviews, TV1 is on screen and TV2 is offscreen. When a user clicks a button TV1 should reduce its size to 1/2 and TV2 should move from offscreen to lower half of the parent view.
I have this code but only the first view is being animated:
func toggleFrames() {
var frame1H = self.view.frame.size.height
var frame2H = CGFloat(0.0)
var frame2Y = CGFloat(0.0)
var txtV1Frame = txtContents.frame
var txtV2Frame = txtChanges.frame
if bViewingChanges {
frame1H = frame1H/2
frame2Y = (self.view.frame.size.height/2) - 10.0
frame2H = frame1H
}
txtV1Frame.size.height = frame1H
txtV2Frame.size.height = frame2H
txtV2Frame.origin.y = 550.0
NSAnimationContext.runAnimationGroup({_ in
NSAnimationContext.current.duration = 0.5
txtContents.animator().frame = txtV1Frame //reduce size of text view 1
txtChanges.animator().frame = txtV2Frame //<--Grumble, not doing anything
}, completionHandler:{
print("Done animation")
})
}

Display values outside of the piechart

I am having trouble displaying the values outside of my piechart. Currently the values overlap, is there anyway to improve this? Please see image below.
chartDataSet.valueLinePart1Length = 0.5
chartDataSet.valueLinePart2Length = 1
//set.xValuePosition = .outsideSlice
chartDataSet.yValuePosition = .outsideSlice
func setupPiChart() {
// This will align label text to top right corner
let l = pieChartView.legend
l.horizontalAlignment = .left
l.verticalAlignment = .bottom
l.orientation = .horizontal
l.xEntrySpace = 10
l.yEntrySpace = 0
l.font = self.isPhone ? Typography.robotoRegular14 : Typography.robotoRegular18
self.pieChartView.entryLabelFont = Typography.robotoRegular14
self.pieChartView.drawHoleEnabled = false
self.pieChartView.drawEntryLabelsEnabled = false
self.pieChartView.notifyDataSetChanged()
}

ios - Swift 4: How to remove UIImageViews when UIImageView.animationImages is finished?

I am using .animationImages for UIImageViews in my project (it's a game). When the user presses a hint button I programmatically create a variable number of UIImageViews that will appear on screen and play the same image sequence once. I need to remove the UIImageViews from the view when the animation has stopped but I can't figure out how to do this.
I've been through the swift documentation for both .animationImages and .startAnimating but it's literally one paragraph and one line, neither of which is in relation to a completion or finish notifications etc. Any help will be much appreciated.
private func hideAnswerButtonsHint() {
// Clear all of the answer boxes that aren't hint locked
resetAnswerBoxes()
var imageArray = [UIImage]()
var remainingLetters = [String]()
for imageCount in 1...8 {
let imageName = "green_smoke_puff_0\(imageCount)"
let image = UIImage(named: imageName)!
imageArray.append(image)
}
for answerBox in answerBoxArray where answerBox.hintLock == false {
if let letter = answerBoxDict[answerBox.tag] {
remainingLetters.append(letter)
}
}
for answerButton in answerButtonArray where answerButton.hintLock == false {
if let index = remainingLetters.index(of: answerButton.titleText) {
answerButton.decompress()
remainingLetters.remove(at: index)
} else {
let frame = answerButton.superview?.convert(answerButton.frame.origin, to: nil)
let imageView = UIImageView()
imageView.animationImages = imageArray
imageView.animationDuration = 0.5
imageView.animationRepeatCount = 1
imageView.frame = CGRect(x: frame!.x, y: frame!.y, width: answerButton.frame.width, height: answerButton.frame.height)
view.addSubview(imageView)
imageView.startAnimating()
answerButton.compress()
answerButton.hintLock = true
}
}
}
UIImageView is an NSObject so you can always use KVO to watch its properties:
var observation: NSKeyValueObservation?
override func viewDidLoad() {
super.viewDidLoad()
observation = imageView.observe(\.isAnimating) { [weak self] imageView, change in
if let value = change.newValue,
value == true {
imageView.removeFromSuperview()
self?.observation = nil
}
}
}

Swift ios 10 NavBar Item keeps growing

I have a navBar Controller connected to a UIView, I have a right bar button item that is a chevron. I have programmatically created a search bar. If you click the chevron about 20-100 times it keeps growing until it is off the screen. I can see each time I click the chevron a slight bump in my search bar. Since you can not place constraints on navBar and fixed Space bar button item does not work either. Any suggestions on where to look or how to fix this?
func rotateChevron(animated: Bool = true) {
let chevAnimate = animated ? 0.3 : 0.0
let chevIsDown = messagePicker.frame.origin.y == self.view.frame.height - (tabBarController?.tabBar.frame.height ?? 0)
let rotation: CGFloat = chevIsDown ? 0.0 : 180.001
UIView.animate(withDuration: chevAnimate, animations: {
self.filterChevron.customView?.transform = CGAffineTransform(rotationAngle: rotation.degreesToRadians)
}, completion: nil)
}
After some research I placed within the animation blocks a forced CGSize (w/h) and this seems to have solved the issue. I also found that transform animation should not be used with frames because it moved the bounds of the image each time which is why the chevron was acting up.
func rotateChevron(animated: Bool = true) {
let chevAnimate = animated ? 0.3 : 0.0
let chevIsDown = messagePicker.frame.origin.y == self.view.frame.height - (tabBarController?.tabBar.frame.height ?? 0)
let rotation: CGFloat = chevIsDown ? 0.0 : 180.001
filterChevron.customView?.frame.size = CGSize(width: 35, height: 30)
UIView.animate(withDuration: chevAnimate, animations: {
self.filterChevron.customView?.transform = CGAffineTransform(rotationAngle: rotation.degreesToRadians)
}, completion: nil)
}