I've got the segment controller above that is connected to the code bellow.
#IBOutlet weak var coatSegmentController: UISegmentedControl!
#IBAction func coatSelectInput() {
switch (self.unitSegmentController.selectedSegmentIndex) {
case 0:
coatSetter = 1
//println("SWITCHED TO coat 1")
println(unitSegmentController.selectedSegmentIndex)
case 1:
coatSetter = 2
//println("SWITCHED TO coat 2")
println(unitSegmentController.selectedSegmentIndex)
case 2:
coatSetter = 3
//println("SWITCHED TO coat 3")
println(unitSegmentController.selectedSegmentIndex)
default:
println("Coat switch did not work")
}
}
No matter what segment I select it always return that I've selected the first segment.
If I hook it to my unit segment outlet it works. But then the unit one stops working.
#IBOutlet weak var unitSegmentController: UISegmentedControl!
Any idea what could that be? I've tried everything. Delete and create again many times. Nothing seems to work.
Here is the full code for the view.
import UIKit
import CoreData
class PaintViewController: UIViewController, UITextFieldDelegate {
//FIELDS *********************************************************
#IBOutlet weak var widthField: UITextField!
#IBOutlet weak var heigthField: UITextField!
#IBOutlet weak var basecoatPriceField: UITextField!
#IBOutlet weak var basecoatCanSizeField: UITextField!
#IBOutlet weak var topcoatPriceField: UITextField!
#IBOutlet weak var topcoatCanSizeField: UITextField!
//FIELD LABELS ***************************************************
#IBOutlet weak var areaToPaintHeader: UILabel!
#IBOutlet weak var basecoatPriceHeader: UILabel!
#IBOutlet weak var topcoatHeader: UILabel!
#IBOutlet weak var basecoatUnit: UILabel!
#IBOutlet weak var topcoatUnit: UILabel!
//RESULT LABELS
#IBOutlet weak var resultBasecoatUnit: UILabel!
#IBOutlet weak var resultBasecoatAmount: UILabel!
#IBOutlet weak var resultBasecoatCost: UILabel!
#IBOutlet weak var resultTopcoatUnit: UILabel!
#IBOutlet weak var resultTopcoatAmount: UILabel!
#IBOutlet weak var resultTopcoatCost: UILabel!
#IBOutlet weak var basecoatNoCostWarning: UILabel!
#IBOutlet weak var topcoatNoCostWarning: UILabel!
// OTHER CONTROLERS
#IBOutlet weak var whatthehell: UISegmentedControl!
#IBOutlet weak var coatSegmentController: UISegmentedControl!
#IBOutlet weak var mainScrollView: UIScrollView!
#IBOutlet weak var unitSegmentController: UISegmentedControl!
// #IBOutlet weak var coatSegController: UISegmentedControl!
// INSTANCES ******************************************************
var unitSetter = "metric"
var coatSetter = 1
//CREATE CONCRETE CORE DATA OBJECT
var paint = [PaintEntity]()
let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
// var calculations = PaintModel(
// width: 0.0,
// heigth: 0.0,
// basecoatPrice: 0.0,
// basecoatCanAmount: 0.0,
// topcoatPrice: 0.0,
// topcoatCanAmount: 0.0,
// unit: "metric",
// coats: 1.0)
// ******************************************************************
// NATIVE METHODS
// ******************************************************************
override func viewDidLoad() {
super.viewDidLoad()
//Empty cost warning label
basecoatNoCostWarning.text = ""
topcoatNoCostWarning.text = ""
// RESET CAN
basecoatCanSizeField.text = "5.0"
topcoatCanSizeField.text = "5.0"
// calculations.basecoatCanAmount = 5.0
// calculations.topcoatCanAmount = 5.0
// APPLY ICON
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 31, height: 36))
imageView.contentMode = .ScaleAspectFit
let image = UIImage(named: "concrete_bag_detail")
imageView.image = image
navigationItem.titleView = imageView
// NAV BAR BG CUSTOM ********************
var navBarColor = navigationController!.navigationBar
// BG COLOR
navBarColor.barTintColor = UIColor(hue: 162/360.0, saturation: 80/100.0, brightness: 45/100.0, alpha: 100.0/100.0)
navBarColor.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.blackColor()]
// STATUS BAR WHITE COLOR ********************
UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent
// DETECT TAP TO TRIGGER HIDE KEYBOARD
let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "hideKeyboard")
tapGesture.cancelsTouchesInView = false
mainScrollView.addGestureRecognizer(tapGesture)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// ******************************************************************
// MY METHODS
// ******************************************************************
// RESET ******************************************************
// func resetDataModel (){
//
//// calculations.width = 0.0
//// calculations.heigth = 0.0
//// calculations.basecoatPrice = 0.0
//// calculations.basecoatCanAmount = 0.0
//// calculations.topcoatPrice = 0.0
//// calculations.topcoatCanAmount = 0.0
//
// }
func resetInputAndLabels(){
widthField.text = ""
heigthField.text = ""
basecoatPriceField.text = ""
topcoatPriceField.text = ""
basecoatNoCostWarning.text = ""
topcoatNoCostWarning.text = ""
resultBasecoatAmount.text = "0.0"
resultBasecoatCost.text = "$0.00"
resultTopcoatAmount.text = "0.0"
resultTopcoatCost.text = "$0.00"
switch unitSetter {
case "metric":
basecoatCanSizeField.text = "5.0"
topcoatCanSizeField.text = "5.0"
basecoatUnit.text = "litre can"
topcoatUnit.text = "litre can"
resultBasecoatUnit.text = "Litres"
resultTopcoatUnit.text = "Litres"
case "imperial":
basecoatCanSizeField.text = "1.0"
topcoatCanSizeField.text = "1.0"
basecoatUnit.text = "gal can"
topcoatUnit.text = "gal can"
resultBasecoatUnit.text = "Gallons"
resultTopcoatUnit.text = "Gallons"
default:
println("Not able to reset labels")
}
}
//ALERT VIEW METHODS ******************************************************
func alertViewLaunch (#message: String){
var alertView = UIAlertView(title: "Ops!", message: message, delegate: self, cancelButtonTitle: "Ok,got it!")
alertView.show()
}
//KEYBOARD RESIZE VIEW ******************************************
// Call this method somewhere in your view controller setup code.
func registerForKeyboardNotifications() {
let notificationCenter = NSNotificationCenter.defaultCenter()
notificationCenter.addObserver(self,
selector: "keyboardWillBeShown:",
name: UIKeyboardWillShowNotification,
object: nil)
notificationCenter.addObserver(self,
selector: "keyboardWillBeHidden:",
name: UIKeyboardWillHideNotification,
object: nil)
}
// Called when the UIKeyboardDidShowNotification is sent.
func keyboardWillBeShown(sender: NSNotification) {
let info: NSDictionary = sender.userInfo!
let value: NSValue = info.valueForKey(UIKeyboardFrameBeginUserInfoKey) as! NSValue
let keyboardSize: CGSize = value.CGRectValue().size
let contentInsets: UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize.height, 0.0)
mainScrollView.contentInset = contentInsets
mainScrollView.scrollIndicatorInsets = contentInsets
// If active text field is hidden by keyboard, scroll it so it's visible
// Your app might not need or want this behavior.
var aRect: CGRect = self.view.frame
aRect.size.height -= keyboardSize.height
}
// Called when the UIKeyboardWillHideNotification is sent
func keyboardWillBeHidden(sender: NSNotification) {
let contentInsets: UIEdgeInsets = UIEdgeInsetsZero
mainScrollView.contentInset = contentInsets
mainScrollView.scrollIndicatorInsets = contentInsets
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.registerForKeyboardNotifications()
}
override func viewDidDisappear(animated: Bool) {
super.viewWillDisappear(animated)
NSNotificationCenter.defaultCenter().removeObserver(self)
}
// HIDE KEYBOARD ON TOUCH ****************************************
func hideKeyboard(){
widthField.resignFirstResponder()
heigthField.resignFirstResponder()
basecoatPriceField.resignFirstResponder()
topcoatPriceField.resignFirstResponder()
basecoatCanSizeField.resignFirstResponder()
topcoatCanSizeField.resignFirstResponder()
}
// *********************************************************************************
// ACTIONS
// *********************************************************************************
#IBAction func resetButton() {
resetInputAndLabels()
// resetDataModel()
}
// CHANGE UNIT **************************************************
#IBAction func unitSelectInput() {
switch unitSegmentController.selectedSegmentIndex {
case 0:
unitSetter = "metric"
resetInputAndLabels()
// resetDataModel()
//println("SWITCHED TO metric")
println(unitSegmentController.selectedSegmentIndex)
case 1:
unitSetter = "imperial"
resetInputAndLabels()
// resetDataModel()
//println("SWITCH TO imperial")
println(unitSegmentController.selectedSegmentIndex)
default:
println("Unit switch did not work")
}
}
// CHANGE COAT **********************************************
#IBAction func coatSelectInput() {
switch (self.unitSegmentController.selectedSegmentIndex) {
case 0:
coatSetter = 1
//println("SWITCHED TO coat 1")
println(unitSegmentController.selectedSegmentIndex)
case 1:
coatSetter = 2
//println("SWITCHED TO coat 2")
println(unitSegmentController.selectedSegmentIndex)
case 2:
coatSetter = 3
//println("SWITCHED TO coat 3")
println(unitSegmentController.selectedSegmentIndex)
default:
println("Coat switch did not work")
}
}
// GENERATE RESULTS **********************************************
#IBAction func generateResults() {
//SCROLL VIEW TO SHOW RESULTS - Only for 4s
let screenSize: CGRect = UIScreen.mainScreen().bounds
//println("Screen heigth - \(screenSize.height)")
if screenSize.height <= 480 {
UIScrollView.animateWithDuration(0.5, delay: 0.0, usingSpringWithDamping: 1.5, initialSpringVelocity: 1.5, options: UIViewAnimationOptions.CurveLinear, animations: {
self.mainScrollView.contentOffset.y = 220.0
}, completion: {
Void in
UIView.animateWithDuration(0.6, delay: 0.0, usingSpringWithDamping: 0.1, initialSpringVelocity: 3.0, options: UIViewAnimationOptions.CurveLinear, animations: {}, completion: { Void in })
})
}
//SAVE TO COREDATA
//DETECT IF NO DATA HAS BEEN ENTERED
if widthField.text == "" || heigthField.text == "" || basecoatCanSizeField.text == "" || topcoatCanSizeField.text == "" {
alertViewLaunch(message: "I will need at least width, heigth, basecoat can size and topcoat can size to get the basic calculations done")
} else {
//STORE DATA DEPENDING ON UNIT
switch unitSetter {
case "metric": PaintEntity.createInManagedObjectContext(self.managedObjectContext!,
width: NSString(string: (widthField.text)).doubleValue,
heigth: NSString(string: (heigthField.text)).doubleValue,
basecoatPrice: NSString(string: (basecoatPriceField.text)).doubleValue,
basecoatCanSize: NSString(string: (basecoatCanSizeField.text)).doubleValue,
topcoatPrice: NSString(string: (topcoatPriceField.text)).doubleValue,
topcoatCanSize: NSString(string: (topcoatCanSizeField.text)).doubleValue,
unit: "metric",
coats: coatSetter)
case "imperial":PaintEntity.createInManagedObjectContext(self.managedObjectContext!,
width: NSString(string: (widthField.text)).doubleValue,
heigth: NSString(string: (heigthField.text)).doubleValue,
basecoatPrice: NSString(string: (basecoatPriceField.text)).doubleValue,
basecoatCanSize: NSString(string: (basecoatCanSizeField.text)).doubleValue,
topcoatPrice: NSString(string: (topcoatPriceField.text)).doubleValue,
topcoatCanSize: NSString(string: (topcoatCanSizeField.text)).doubleValue,
unit: "imperial",
coats: coatSetter)
default:
println("No unit detected")
}
printResults()
}
}
func printResults(){
let fetchRequest = NSFetchRequest(entityName: "PaintEntity")
let sortDescriptor = NSSortDescriptor(key: "date", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
fetchRequest.fetchLimit = 1
var error : NSError?
if let fetchResults = managedObjectContext!.executeFetchRequest(fetchRequest, error: &error) as? [PaintEntity] {
resultBasecoatAmount.text = "\(roundNumberToOne(fetchResults[0].resultBasecoatAmount.doubleValue))"
resultTopcoatAmount.text = "\(roundNumberToOne(fetchResults[0].resultTopcoatAmount.doubleValue))"
//println("I am fetching this \(fetchResults[0])")
if basecoatPriceField.text == "" || topcoatPriceField.text == "" {
resultBasecoatCost.textColor = UIColor(hue: 162/360.0, saturation: 65/100.0, brightness: 45/100.0, alpha: 100.0/100.0)
basecoatNoCostWarning.text = "Missing price"
resultBasecoatCost.text = "$0.00"
resultTopcoatCost.textColor = UIColor(hue: 162/360.0, saturation: 65/100.0, brightness: 45/100.0, alpha: 100.0/100.0)
topcoatNoCostWarning.text = "Missing price"
resultTopcoatCost.text = "$0.00"
}else{
if basecoatPriceField == "" {
resultBasecoatCost.textColor = UIColor(hue: 162/360.0, saturation: 65/100.0, brightness: 45/100.0, alpha: 100.0/100.0)
basecoatNoCostWarning.text = "Missing price"
resultBasecoatCost.text = "$0.00"
} else {
resultBasecoatCost.textColor = UIColor.whiteColor()
basecoatNoCostWarning.text = ""
resultBasecoatCost.text = "$\(roundNumberToTwo(fetchResults[0].resultBasecoatCost.doubleValue))"
}
if topcoatPriceField == "" {
resultTopcoatCost.textColor = UIColor(hue: 165/360.0, saturation: 63/100.0, brightness: 53/100.0, alpha: 100.0/100.0)
topcoatNoCostWarning.text = "Missing price"
resultTopcoatCost.text = "$0.00"
}else{
resultTopcoatCost.textColor = UIColor.whiteColor()
topcoatNoCostWarning.text = ""
resultTopcoatCost.text = "$\(roundNumberToTwo(fetchResults[0].resultTopcoatCost.doubleValue))"
}
}
}
}
}
Related
I would like to make sure that my cell has a background related to the remaining time. in the sense that the closer I get to 0, the more I would like it to be reduced, so that we understand that the timer is about to expire.
according to the elapsed time it automatically reduces from right to left.
this is the code I use in managing the Cell
class TimerCell: UITableViewCell {
#IBInspectable var defaultBackgroundColor: UIColor = .white
#IBInspectable var runningBackgroundColor: UIColor = .white
#IBInspectable var pausedBackgroundColor: UIColor = .white
#IBInspectable var animationDuration: Double = 0
#IBOutlet var timeLabel: UILabel!
#IBOutlet var nameLabel: UILabel!
#IBOutlet var startButton: UIButton!
#IBOutlet var pauseButton: UIButton!
#IBOutlet var stopButton: UIButton!
weak var timer: Timer? {
didSet {
guard let timer = timer else {
updater?.invalidate()
return
}
if case .running = timer.state {
startUpdater()
}
configure(animated: false)
}
}
private weak var updater: Foundation.Timer?
override func awakeFromNib() {
super.awakeFromNib()
}
override func setEditing(_ editing: Bool, animated: Bool) {
print("*** \(Date()) setEditing(\(editing), animated: \(animated)) (timer?.name: \(String(describing: timer?.name)))")
super.setEditing(editing, animated: animated)
configure(animated: animated)
}
func configure(animated: Bool = true) {
guard let timer = timer else {
return
}
UIView.animate(withDuration: animated ? animationDuration : 0) {
guard !self.isEditing else {
self.timeLabel.text = timer.initialTime.hmsString
self.startButton.safelySetIsHidden(true)
self.pauseButton.safelySetIsHidden(true)
self.stopButton.safelySetIsHidden(true)
self.backgroundColor = self.defaultBackgroundColor
return
}
self.timeLabel.text = ceil(timer.timeForState).hmsString
self.nameLabel.text = timer.name
switch timer.state {
case .stopped:
self.stopButton.safelySetIsHidden(true)
self.pauseButton.safelySetIsHidden(true)
self.startButton.safelySetIsHidden(false)
self.backgroundColor = self.defaultBackgroundColor
case .running:
self.startButton.safelySetIsHidden(true)
self.stopButton.safelySetIsHidden( ceil(timer.timeForState) == 0 ? true : false )
self.pauseButton.safelySetIsHidden( ceil(timer.timeForState) == 0 ? true : false )
self.backgroundColor = self.runningBackgroundColor
case .paused:
self.pauseButton.safelySetIsHidden(true)
self.startButton.safelySetIsHidden(false)
self.stopButton.safelySetIsHidden(false)
self.backgroundColor = self.pausedBackgroundColor
}
}
}
#IBAction private func startTimer() {
timer?.state = .running
configure()
startUpdater()
}
#IBAction private func pauseTimer() {
timer?.state = .paused
configure()
}
#IBAction private func stopTimer() {
timer?.state = .stopped
configure()
}
private func startUpdater() {
guard let timer = timer else {
return
}
let date = Date(timeIntervalSinceNow: timer.timeForState.truncatingRemainder(dividingBy: 1))
let updater = Foundation.Timer(fire: date, interval: 1, repeats: true) {
[weak timer] updater in
self.configure()
if timer?.state != .running {
updater.invalidate()
}
}
self.updater = updater
RunLoop.main.add(updater, forMode: .common)
}
}
I think you're after something like this:
That's not trivial to achieve. I did it by adding a CAGradientLayer to the view and animating its locations property. At the same time, I ran the timer to change the label value.
So you might do it that way; you would probably want to tweak the values, of course. This is just a proof-of-concept demo.
I am new to Swift. I'm currently learning structure module.
I was asked to create a score that increases 1 point each time the user gets an answer right, but my score ends up increased by 2. I am so confused. Everything else is fine. Can someone help me out please?
My code is below:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var questionLable: UILabel!
#IBOutlet weak var progressBar: UIProgressView!
#IBOutlet weak var trueButton: UIButton!
#IBOutlet weak var falseButton: UIButton!
#IBOutlet weak var scoreLabel: UILabel!
var quizBrain = QuizBrain()
override func viewDidLoad() {
super.viewDidLoad()
progressBar.progress = 0
updatedUI()
}
#IBAction func answerButtonPressed(_ sender: UIButton) {
let userAnswer = sender.currentTitle!
let userGotItRight = quizBrain.checkAnswer(userAnswer)
print(quizBrain.checkAnswer(userAnswer))
if userGotItRight{
UIView.animate(withDuration: 0.2) {
sender.backgroundColor = #colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 1)
}
UIView.animate(withDuration: 0.2) {
sender.backgroundColor = UIColor.clear
}
}else{
UIView.animate(withDuration: 0.2) {
sender.backgroundColor = #colorLiteral(red: 0.9098039269, green: 0.4784313738, blue: 0.6431372762, alpha: 1)
}
UIView.animate(withDuration: 0.2) {
sender.backgroundColor = UIColor.clear
}
}
quizBrain.nextQuestion()
updatedUI()
}
func updatedUI() {
questionLable.text = quizBrain.getQuestionText()
scoreLabel.text = "Score:\(quizBrain.getScore())"
progressBar.progress = quizBrain.getProgress()
}
}
The next part is Model:
import Foundation
struct QuizBrain {
let quiz = [
Question(q: "A slug's blood is green.", a: "True"),
Question(q: "Approximately one quarter of human bones are in the feet.", a: "True"),
Question(q: "The total surface area of two human lungs is approximately 70 square metres.", a: "True"),
Question(q: "Chocolate affects a dog's heart and nervous system; a few ounces are enough to kill a small dog.", a: "True")
]
var questionNumber = 0
var score = 0
mutating func checkAnswer(_ userAnswer: String) -> Bool {
if userAnswer == quiz[questionNumber].answer{
score += 1
return true
}else{
return false
}
}
mutating func getScore() -> Int {
return score
}
func getQuestionText() -> String {
return quiz[questionNumber].text
}
func getProgress() -> Float {
let progress = Float(questionNumber + 1)/Float(quiz.count)
return progress
}
mutating func nextQuestion(){
if questionNumber + 1 < quiz.count{
questionNumber += 1
}else {
questionNumber = 0
score = 0
}
}
}
Your problem is in these two lines:
let userGotItRight = quizBrain.checkAnswer(userAnswer)
print(quizBrain.checkAnswer(userAnswer))
In the first line, you check the answer to see if it is true. If true, it increments by one, but in the next line, you want to just print the result, but you actually call the checkAnswer again, which increments it one more time.
Perhaps you could change the two lines to look like this:
let userGotItRight = quizBrain.checkAnswer(userAnswer)
print(userGotItRight)
I was working on trying to get a background view for a project I'm making and came across a weird instance.
This is how my code is set up.
import Foundation
import UIKit
class MainMenuViewController: UIViewController, CAAnimationDelegate {
#IBOutlet weak var colorView: UIView!
#IBOutlet weak var startLabel: UILabel!
#IBOutlet weak var firstButton: UIButton!
#IBOutlet weak var secondButton: UIButton!
#IBOutlet weak var thirdButton: UIButton!
let gradient = CAGradientLayer()
var gradientSet = [[CGColor]]()
var currentGradient: Int = 0
let gradientOne = gradientColors.lightGrey.cgColor
let gradientTwo = gradientColors.darkGrey.cgColor
let gradientThree = gradientColors.veryDarkGrey.cgColor
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
gradientSet.append([gradientOne, gradientTwo])
gradientSet.append([gradientTwo, gradientThree])
gradientSet.append([gradientThree, gradientOne])
gradient.frame = colorView.bounds
gradient.colors = gradientSet[currentGradient]
gradient.startPoint = CGPoint(x:0, y:0)
gradient.endPoint = CGPoint(x:1, y:1)
gradient.drawsAsynchronously = true
colorView.layer.insertSublayer(gradient, below: thirdButton.layer)
animateGradient()
}
func animateGradient() {
if currentGradient < gradientSet.count - 1 {
currentGradient += 1
} else {
currentGradient = 0
}
let gradientChangeAnimation = CABasicAnimation(keyPath: "colors")
gradientChangeAnimation.duration = 5.0
gradientChangeAnimation.toValue = gradientSet[currentGradient]
gradientChangeAnimation.fillMode = CAMediaTimingFillMode.forwards
gradientChangeAnimation.isRemovedOnCompletion = false
gradient.add(gradientChangeAnimation, forKey: "colorChange")
}
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
if flag == true {
print("animation complete")
gradient.colors = gradientSet[currentGradient]
animateGradient()
}
}
}
The problem I'm having is that when the animation is finished, the 'animationDidStop' never triggers. The first animation runs, but when it's finished it's supposed to run the 'animationDidStop' function and run the 'animateGradient' function on a constant loop. I've looked and looked for solutions online but can't seem to find one. Im running Swift 4 and would really appreciate any help. Thanks!
You left out a line:
gradientChangeAnimation.delegate = self
I have an IBAction wired up to a button in my storyboard that plays a sound. This works just fine. However, when I wire up an IBOutlet to the same button, the code for the outlet takes over and the IBAction stops working. In this case, the IBOutlet serves the purpose of making the button pulse with animation. Here is my code:
import UIKit
import Firebase
import AVFoundation
class Page1: UIViewController, AVAudioPlayerDelegate, UIAlertViewDelegate {
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var pageControl: UIPageControl!
#IBOutlet weak var testpulse: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
let url = Bundle.main.url(forResource: "ahh", withExtension: "mp3")
do {
ahh = try AVAudioPlayer(contentsOf: url!)
ahh.prepareToPlay()
}
catch let error as NSError {
print(error.debugDescription)
}
testpulse.isUserInteractionEnabled = true
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(Page1.addPulse))
tapGestureRecognizer.numberOfTapsRequired = 1
testpulse.addGestureRecognizer(tapGestureRecognizer)
}
#objc func addPulse(){
let pulse = Pulsing(numberOfPulses: 1, radius: 110, position: testpulse.center)
pulse.animationDuration = 0.8
pulse.backgroundColor = UIColor.purple.cgColor
self.view.layer.insertSublayer(pulse, below: testpulse.layer)
}
#IBAction func ahh(_ sender: Any) {
ahh.play()
}
}
And for my Swift animation file I have this:
import UIKit
class Pulsing: CALayer {
var animationGroup = CAAnimationGroup()
var initialPulseScale:Float = 0
var nextPulseAfter:TimeInterval = 0
var animationDuration:TimeInterval = 1.5
var radius:CGFloat = 200
var numberOfPulses:Float = Float.infinity
override init(layer: Any) {
super.init(layer: layer)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
init (numberOfPulses:Float = Float.infinity, radius:CGFloat, position:CGPoint) {
super.init()
self.backgroundColor = UIColor.black.cgColor
self.contentsScale = UIScreen.main.scale
self.opacity = 0
self.radius = radius
self.numberOfPulses = numberOfPulses
self.position = position
self.bounds = CGRect(x: 0, y: 0, width: radius * 2, height: radius * 2)
//self.cornerRadius = radius
DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async {
self.setupAnimationGroup()
DispatchQueue.main.async {
self.add(self.animationGroup, forKey: "pulse")
}
}
setupAnimationGroup()
self.add(animationGroup, forKey: "pulse")
}
func createScaleAnimation () -> CABasicAnimation {
let scaleAnimation = CABasicAnimation(keyPath: "transform.scale.xy")
scaleAnimation.fromValue = NSNumber(value: initialPulseScale)
scaleAnimation.toValue = NSNumber(value: 1)
scaleAnimation.duration = animationDuration
return scaleAnimation
}
func createOpacityAnimation() -> CAKeyframeAnimation? {
let opacityAnimation = CAKeyframeAnimation(keyPath: "opacity")
opacityAnimation.duration = animationDuration
opacityAnimation.values = [0.4, 0.8, 0]
opacityAnimation.keyTimes = [0, 0.2, 1]
return opacityAnimation
}
func setupAnimationGroup() {
self.animationGroup = CAAnimationGroup()
self.animationGroup.duration = animationDuration + nextPulseAfter
self.animationGroup.repeatCount = numberOfPulses
let defaultCurve = CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)
self.animationGroup.timingFunction = defaultCurve
self.animationGroup.animations = [createScaleAnimation(), createOpacityAnimation()!]
}
}
When I connect the IBAction to my button, the sound works. However when I connect the IBOutlet, the animation works but the IBAction doesn't. What could be causing this? It's still connected in the storyboard.
import UIKit
import Firebase
import AVFoundation
class Page1: UIViewController, AVAudioPlayerDelegate, UIAlertViewDelegate {
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var pageControl: UIPageControl!
#IBOutlet weak var testpulse: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
let url = Bundle.main.url(forResource: "ahh", withExtension: "mp3")
do {
ahh = try AVAudioPlayer(contentsOf: url!)
ahh.prepareToPlay()
}
catch let error as NSError {
print(error.debugDescription)
}
testpulse.isUserInteractionEnabled = true
}
#objc func addPulse(){
let pulse = Pulsing(numberOfPulses: 1, radius: 110, position: testpulse.center)
pulse.animationDuration = 0.8
pulse.backgroundColor = UIColor.purple.cgColor
self.view.layer.insertSublayer(pulse, below: testpulse.layer)
}
#IBAction func ahh(_ sender: Any) {
ahh.play()
addPulse()
}
}
I am creating a OSX app and would like to enable a button when all textfield are filled. But do not have much experience with osx app as there seem to be some difference from ios.
This is what I have tried.
override func viewDidLoad() {
super.viewDidLoad()
btnCalculate.enabled = false
}
override func controlTextDidChange(obj: NSNotification) {
if panelsWideTextField.stringValue.isEmpty {
btnCalculate.enabled = false
} else {
btnCalculate.enabled = true
}
}
Hope someone has a good tip for me :-)
EDIT:
Complete code.
import Cocoa
//import AppKit
class ViewController: NSViewController, NSTextFieldDelegate {
#IBOutlet weak var panelHightTextField: NSTextField!
#IBOutlet weak var panelWidthTextField: NSTextField!
#IBOutlet weak var panelPitchTextField: NSTextField!
#IBOutlet weak var panelsHighTextField: NSTextField!
#IBOutlet weak var panelsWideTextField: NSTextField!
#IBOutlet weak var resWidthLabel: NSTextField!
#IBOutlet weak var resHightLabel: NSTextField!
#IBOutlet weak var lblScreenWidth: NSTextField!
#IBOutlet weak var lblScreenHight: NSTextField!
#IBOutlet weak var lblScreenArea: NSTextField!
#IBOutlet weak var btnCalculate: NSButton!
#IBOutlet weak var lblAmountPanels: NSTextField!
var panelHight = ""
var panelWidth = ""
var panelPitch = ""
var panelsHigh = ""
var panelsWidth = ""
var resWidth : Float = 0
var resHigh : Float = 0
var screenHight : Float = 0
var screenWidth : Float = 0
var screenArea : Float = 0
var ammountPanels : Float = 0
override func viewDidLoad() {
super.viewDidLoad()
btnCalculate.enabled = false
}
override func controlTextDidChange(obj: NSNotification) {
if panelsWideTextField.stringValue.isEmpty {
btnCalculate.enabled = true
} else {
btnCalculate.enabled = false
}
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
#IBAction func calculateResButton(sender: AnyObject) {
takeUserData()
calculatehight()
calculatewidth()
calculateArea()
calculateAmountPanels()
}
func takeUserData(){
panelHight = panelHightTextField.stringValue
panelWidth = panelWidthTextField.stringValue
panelPitch = panelPitchTextField.stringValue
panelsHigh = panelsHighTextField.stringValue
panelsWidth = panelsWideTextField.stringValue
}
// Calculating resolution and physical hight
func calculatehight(){
let fpanelHight = Float(panelHight)
let fpanelPitch = Float(panelPitch)
let fpanelsHigh = Float(panelsHigh)
resHigh = fpanelHight! * fpanelsHigh! / fpanelPitch!
screenHight = fpanelHight! * fpanelsHigh! / 1_000
printText()
}
// Calculating resolution and physical width
func calculatewidth(){
let fpanelWidth = Float(panelWidth)
let fpanelPitch = Float(panelPitch)
let fpanelsWidth = Float(panelsWidth)
resWidth = fpanelWidth!*fpanelsWidth!/fpanelPitch!
screenWidth = fpanelWidth!*fpanelsWidth! / 1_000
printText()
}
// Calculating sqm of LED screen
func calculateArea(){
let fpanelHight = Float(panelHight)
let fpanelsHigh = Float(panelsHigh)
let fpanelWidth = Float(panelWidth)
let fpanelsWidth = Float(panelsWidth)
screenArea = (fpanelHight! * fpanelsHigh!) * (fpanelWidth! * fpanelsWidth!) / 1_000_000
printText()
}
// Calculating the amount of panels used.
func calculateAmountPanels(){
let fpanelsHigh = Float(panelsHigh)
let fpanelsWidth = Float(panelsWidth)
ammountPanels = (fpanelsWidth! * fpanelsHigh!)
printText()
}
// Outputting text to labels with correct format.
func printText(){
let formatResHigh = String(format: "%0.0f", resHigh)
let formatResWidth = String(format: "%0.0f", resWidth)
let formatScreenHight = String(format: "%0.2f", screenHight)
let formatScreenWidth = String(format: "%0.2f", screenWidth)
let formatScreenArea = String(format: "%0.0f", screenArea)
let formatAmmountPanels = String(format: "%0.0f", ammountPanels)
resHightLabel.stringValue = "\(formatResHigh)px"
resWidthLabel.stringValue = "\(formatResWidth)px"
lblScreenHight.stringValue = "\(formatScreenHight)m"
lblScreenWidth.stringValue = "\(formatScreenWidth)m"
lblScreenArea.stringValue = "\(formatScreenArea) sqm"
lblAmountPanels.stringValue = "\(formatAmmountPanels)"
}
}
I had the same problem but I found simple solution: checkbox can enable and disable NSButton.
import Cocoa
class ViewController: NSViewController {
#IBOutlet weak var btnCalculate: NSButton!
#IBOutlet weak var checkBox: NSButton!
override func viewDidLoad() {
super.viewDidLoad()
btnCalculate.enabled = false
checkBox.state = 0
}
#IBAction func checkAgree(sender: NSButton) {
if btnCalculate.stringValue.characters.count > 0 && checkBox.state == 1 {
btnCalculate.enabled = true
} else {
btnCalculate.enabled = false
}
}
}