Issue when passing data through segue in swift2 [duplicate] - ios

This is a Tip Calculator Project and It must have a settings view where I select the default tip rate. I have some issues with passing data, when I select a default tip percentage it doesn't change in the View Controller, also I want to make the app remember the default rate when I close the app and reopened. I will really appreciate that some one corrects my code and test it. This is for entering a Computer Science Program in college, I don't have previous experience with any programming language before.
100
TipPercentageLabel.text = "(tipDisplay)%"
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func setupContainer() {
tipSlider.minimumValue = 0
tipSlider.maximumValue = 100
tipSlider.value = 20
tipSlider.addTarget(self, action: "sliderTipChanged:", forControlEvents: .ValueChanged)
personsStepper.minimumValue = 1
personsStepper.maximumValue = 30
personsStepper.value = 1
personsStepper.addTarget(self, action: "sliderPersonChanged:", forControlEvents: .ValueChanged)
amountTextField.text = ""
refreshCalculation()
}
#IBAction func OnEditingFieldBill(sender: AnyObject) {
refreshCalculation()
}
func refreshCalculation() {
numberFormatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
if let amount = numberFormatter.numberFromString(amountTextField.text!) as? Double {
let tipAmount = amount * tipPercentage
let totalBill = amount + tipAmount
let billPerPerson = totalBill / Double(numberOfPerson)
numberFormatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
tipAmountLabel.text = numberFormatter.stringFromNumber(tipAmount)
totalBillLabel.text = numberFormatter.stringFromNumber(totalBill)
billPerPersonLabel.text = numberFormatter.stringFromNumber(billPerPerson)
} else {
tipAmountLabel.text = "-"
totalBillLabel.text = "-"
billPerPersonLabel.text = "-"
}
numberFormatter.numberStyle = NSNumberFormatterStyle.PercentStyle
numberFormatter.minimumFractionDigits = 1
numberFormatter.maximumFractionDigits = 1
TipPercentageLabel.text = self.numberFormatter.stringFromNumber(tipPercentage)
numberOfPersonLabel.text = "\(numberOfPerson)"
}
#IBAction func sliderTipChanged(sender: AnyObject) {
tipPercentage = Double(round(tipSlider.value)) / 100
refreshCalculation()
}
#IBAction func StepperPersonChanged(sender: AnyObject) {
numberOfPerson = Int(round(personsStepper.value))
refreshCalculation()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let id = segue.identifier {
if id == "show settings" {
if let SettingsViewController = segue.destinationViewController as? SettingsViewController {
}
}
}
}
}
SETTINGS VIEW CONTROLLER
import UIKit
class SettingsViewController: UIViewController {
#IBOutlet weak var tipControl: UISegmentedControl!
var tipRates:Double?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func DefaultRate(sender: AnyObject) {
va
if let tip = tipRates {
ViewController.tipPercentage = tip/100

Replace you DefaultRate IBAction with this:
#IBAction func changevalue(sender: UISegmentedControl) {
var tipRate = [5, 10, 15, 20, 25, 30]
tipRates = Double(tipRate[tipControl.selectedSegmentIndex])
delegate?.tipPercentageChanged(tipRates!) print("(tipRates)")
NSUserDefaults.standardUserDefaults().setDouble(tipRates!, forKey: "DefaultTipRate")
NSUserDefaults.standardUserDefaults().synchronize()
}
And set the event as "Value Changed" as shown in the image below

I strongly recommend you go through a few introductory iOS & Swift tutorials online. SO is not the place to get beginner level understanding of programming topics. Some recommended tutorials:
Swift 2 Tutorial
Apple swift tutorials

Related

UIImageView image changes with different songs

I have a simple media player and I'm trying to make it change the artwork image as the songs change. With the code I have now it will display the artwork when you hit play but when I hit the next button to skip to the next item it stays the same unless you hit another button.
How can I make the UIImageView image change as the song media item changes?
import UIKit
import MediaPlayer
class ViewController: UIViewController {
#IBOutlet weak var coverImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
createQueue()
}
func showArt(){
coverImageView.image =
myMediaPlayer.nowPlayingItem?.artwork!.image(at: CGSize.init(width: 500, height: 500))
coverImageView.isUserInteractionEnabled = true
}
#IBAction func playButton(_ sender: UIButton) {
togglePlay(on: sender)
showArt()
}
#IBAction func backButton(_ sender: UIButton) {
back()
}
#IBAction func nextButton(_ sender: UIButton) {
skip()
}
}
My other functions are as followed:
import MediaPlayer
let myMediaPlayer = MPMusicPlayerApplicationController.systemMusicPlayer
let playDrake = MPMediaPropertyPredicate(value: "Drake", forProperty: MPMediaItemPropertyArtist, comparisonType: MPMediaPredicateComparison.equalTo)
let myFilterSet: Set<MPMediaPropertyPredicate> = [playDrake]
func createQueue() {
let drakeQuery = MPMediaQuery(filterPredicates: myFilterSet)
myMediaPlayer.setQueue(with: drakeQuery)
}
func skip() {
myMediaPlayer.skipToNextItem()
}
func back() {
if myMediaPlayer.currentPlaybackTime > 0.05 {
myMediaPlayer.skipToPreviousItem()
} else if myMediaPlayer.currentPlaybackTime < 0.05 {
myMediaPlayer.skipToBeginning()
} else {
//do nothing
}
}
func togglePlay(on: UIButton) {
if myMediaPlayer.playbackState.rawValue == 2 || myMediaPlayer.playbackState.rawValue == 0 {
on.setTitle("Pause", for: UIControlState.normal)
myMediaPlayer.play()
} else if myMediaPlayer.playbackState.rawValue == 1{
on.setTitle("Play", for: UIControlState.normal)
myMediaPlayer.pause()
} else {
// do nothing
}
}
Try loading the image asynchronously
DispatchQueue.global(qos: .background).async {
myMediaPlayer.nowPlayingItem?.artwork!.image(at: CGSize.init(width: 500, height: 500))
}

Generating Random UIImages that don't repeat

In my app project I am displaying 107 of my images at random, I have set up a for loop that puts all of my images into an array. I then take that array and choose a random Index. That index correlates to a picture and then that picture appears on the screen when the user swipes to the left. My question is that can I make it so my code will not repeat the same index in the array until all of them (or the amount until closing the app) have been chosen at random. Here is my code
class ViewController: UIViewController {
var pictureArray: [String] = []
#IBOutlet weak var quoteImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
for i in 0...107{
pictureArray.append("quote\(i).jpg")
print(pictureArray)
}
// Do any additional setup after loading the view, typically from a nib.
let swipeRecognizer = UISwipeGestureRecognizer(target: self, action: #selector (changeQuotes))
swipeRecognizer.direction = UISwipeGestureRecognizerDirection.left
self.view.addGestureRecognizer(swipeRecognizer)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override var prefersStatusBarHidden: Bool{
return true
}
#objc func changeQuotes(){
let numberOfImages: UInt32 = 107
let randomIndex = Int(arc4random_uniform(UInt32(pictureArray.count)))
let imageName = "\(pictureArray[randomIndex])"
print(imageName)
quoteImage.image = UIImage(named: imageName)
}
}
Thanks for any help!
Flush your array randomly, then just get the "sorted" image one by one.
extension Sequence {
func randomSorted() -> [Element] {
var result = Array(self)
guard result.count > 1 else { return result }
for (i, k) in zip(result.indices, stride(from: result.count, to: 1, by: -1)) {
let newIndex = Int(arc4random_uniform(UInt32(k)))
if newIndex == i { continue }
result.swapAt(i, newIndex)
}
return result
}
}
You can generate unique random number by managing 2 arrays one contains images that are not yet displayed and one that are already displayed
Make following changes in your code
var pictureArray: [String] = []
var selectedPictureArray: [String] = []
static let TOTAL_IMAGES = 108
#IBOutlet weak var quoteImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
self.fillPictureArray()
let swipeRecognizer = UISwipeGestureRecognizer(target: self, action: #selector (changeQuotes))
swipeRecognizer.direction = UISwipeGestureRecognizerDirection.left
self.view.addGestureRecognizer(swipeRecognizer)
}
func fillPictureArray() {
self.selectedPictureArray.removeAll()
for i in 0..<ViewController.TOTAL_IMAGES {
pictureArray.append("quote\(i).jpg")
}
print(pictureArray)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override var prefersStatusBarHidden: Bool{
return true
}
func changeQuotes(){
if self.pictureArray.count == 0 {
self.fillPictureArray()
}
var randomIndex = 0
while true {
randomIndex = Int(arc4random_uniform(UInt32(ViewController.TOTAL_IMAGES)))
if self.selectedPictureArray.contains("quote\(randomIndex).jpg") {
continue
}else {
break
}
}
let imageName = "quote\(randomIndex).jpg"
self.selectedPictureArray.append(imageName)
print(imageName)
quoteImage.image = UIImage(named: imageName)
let index = self.pictureArray.index(of: imageName)
self.pictureArray.remove(at: index!)
}
Happy coding :)

type "viewController" does not conform protocol "PathMenuDelegate"

I just start learning swift.
I installed Cocoapod and tried to see if i can implemented.
i truly dont know how to fix this problem, the rest of the code will be provided down below.
override func viewDidLoad() {
super.viewDidLoad()
let menuItemImage = UIImage(named: "bg-menuitem")!
let menuItemHighlitedImage = UIImage(named: "bg-menuitem-highlighted")!
let starImage = UIImage(named: "icon-star")!
let starMenuItem1 = PathMenuItem(image: menuItemImage, highlightedImage: menuItemHighlitedImage, contentImage: starImage)
let starMenuItem2 = PathMenuItem(image: menuItemImage, highlightedImage: menuItemHighlitedImage, contentImage: starImage)
let starMenuItem3 = PathMenuItem(image: menuItemImage, highlightedImage: menuItemHighlitedImage, contentImage: starImage)
let starMenuItem4 = PathMenuItem(image: menuItemImage, highlightedImage: menuItemHighlitedImage, contentImage: starImage)
let starMenuItem5 = PathMenuItem(image: menuItemImage, highlightedImage: menuItemHighlitedImage, contentImage: starImage)
let items = [starMenuItem1, starMenuItem2, starMenuItem3, starMenuItem4, starMenuItem5]
let startItem = PathMenuItem(image: UIImage(named: "bg-addbutton")!,
highlightedImage: UIImage(named: "bg-addbutton-highlighted"),
contentImage: UIImage(named: "icon-plus"),
highlightedContentImage: UIImage(named: "icon-plus-highlighted"))
let menu = PathMenu(frame: view.bounds, startItem: startItem, items: items)
menu.delegate = self
menu.startPoint = CGPointMake(UIScreen.mainScreen().bounds.width/2, self.view.frame.size.height - 30.0)
menu.menuWholeAngle = CGFloat(M_PI) - CGFloat(M_PI/5)
menu.rotateAngle = -CGFloat(M_PI_2) + CGFloat(M_PI/5) * 1/2
menu.timeOffset = 0.0
menu.farRadius = 110.0
menu.nearRadius = 90.0
menu.endRadius = 100.0
menu.animationDuration = 0.5
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Delegate protocol (PathMenuDelegate)
_ how to implement the rest of code show below into the viewDidLoad
func pathMenu(menu: PathMenu, didSelectIndex idx: Int)
func pathMenuDidFinishAnimationClose(menu: PathMenu)
func pathMenuDidFinishAnimationOpen(menu: PathMenu)
func pathMenuWillAnimateOpen(menu: PathMenu)
func pathMenuWillAnimateClose(menu: PathMenu)
    
class ViewController: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
~~~
menu.delegate = self
self.view.addSubview(menu)
}
}
extension ViewController: PathMenuDelegate {
func didSelect(on menu: PathMenu, index: Int) {
print("Select the index : \(index)")
}
func willStartAnimationOpen(on menu: PathMenu) {
print("Menu will open!")
}
func willStartAnimationClose(on menu: PathMenu) {
print("Menu will close!")
}
func didFinishAnimationOpen(on menu: PathMenu) {
print("Menu was open!")
}
func didFinishAnimationClose(on menu: PathMenu) {
print("Menu was closed!")
}
}
You can't put these code in viewDidLoad.
Make the respective viewController conform to the PathMenuDelegate
And Start typing the protocol functions you'll get suggestions for 'em
Everything you're questioning, just see the author's sample code here: Very simple and straight forward. Those delegate's functions are just for handling events from the lib. And the sample here just prints something to show you that, "Your code works".
https://github.com/pixyzehn/PathMenu/blob/master/PathMenu-Sample/PathMenu-Sample/ViewController.swift

Counting up/down numbers animation

I have an UIPageViewController with a number in the center of each VC in it.
I want that when I swipe from view to view, the number will begin at 0 and count up until it gets to the correct number (or if the number is negative - count down) like in this gif:
https://d13yacurqjgara.cloudfront.net/users/345970/screenshots/2126044/shot.gif
How can I do that?
Thank you!
You can use NSTimer to achieve this.
Here is example project I created for you.
Create layout like this:
Then in your ViewController do like so:
import UIKit
class ViewController: UIViewController {
#IBOutlet var countingLabel: UILabel!
var number = 0
var destinationNumber = 30
var timer: NSTimer!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func startButtonTapped(sender: AnyObject) {
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "countUp", userInfo: nil, repeats: true)
}
func countUp() {
if number < destinationNumber {
number += 1
countingLabel.text = "\(number)"
} else {
timer.invalidate()
}
}
}
It will work.
Do not overcomplicate with timers and invalidations, etc.
extension UILabel {
func countAnimation(upto: Double) {
let from: Double = text?.replace(string: ",", replacement: ".").components(separatedBy: CharacterSet.init(charactersIn: "-0123456789.").inverted).first.flatMap { Double($0) } ?? 0.0
let steps: Int = 20
let duration = 0.350
let delay = duration / Double(steps)
let diff = upto - from
for i in 0...steps {
DispatchQueue.main.asyncAfter(deadline: .now() + delay * Double(i)) {
self.text = "\(from + diff * (Double(i) / Double(delay)))"
}
}
}
}

Application freezing when I press button

So, my assignment for my class is to make an app for the 7th graders at my school to work on math.
In this particular view controller, I am making something that they can practice prime numbers with. I couldn't get everything to load using the override func viewDidLoad(){} so I implemented a button to activate the random number, modulus to check if it's prime, and insert it into the label.
This is ALL of my code that is inside of the Class:
#IBAction func primeBack(sender: UIButton) {
self.performSegueWithIdentifier("primeBack", sender: nil)
}
#IBOutlet var start: UIButton!
#IBOutlet var primeNum: UILabel!
var num = 1
var check = Double()
var temp2 = Double()
let lower : UInt32 = 1
let upper : UInt32 = 100
override func viewDidLoad() {
super.viewDidLoad()
primeNum.hidden = true
start.hidden = false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func start(sender: UIButton) {
primeNum.hidden = false
let temp1 = (arc4random_uniform(upper - lower) + lower)
primeNum.text = String(temp1)
while num <= 12
{
check = Double(temp1) / Double(num)
temp2 = check % 1
if temp2 == 0
{
num++
}
else
{
num = 12
}
}
start.hidden = true
}
#IBAction func prime(sender: UIButton) {
if temp2 == 0
{
self.performSegueWithIdentifier("primeCorrect", sender: nil)
}
else
{
self.performSegueWithIdentifier("primeIncorrect", sender: nil)
}
}
#IBAction func notPrime(sender: UIButton) {
if temp2 == 0
{
self.performSegueWithIdentifier("primeIncorrect", sender: nil)
}
else
{
self.performSegueWithIdentifier("primeCorrect", sender: nil)
}
}
Debug and watch what happens to your value of temp2. I suspect it never becomes equal to zero, hence your while loop never ends

Resources