2015-11-17 40 views
0

我問大約一個星期前這個問題的一部分,並得到否決了,所以我花了時間它正在努力解決它。我已經研究過如何完成在UIPicker和函數之間傳遞的第一部分。我創建了一個類calculateTime(),裏面是我的函數,它接受一個數組作爲參數。然後計算一個我標籤計數的數字。 接下來我需要做的是通過update()函數的計數,以便我可以使用倒數計時器更新文本標籤。無論我把這個功能放在哪裏,我都無法讓它工作。如果它在課堂內部,我會得到一個選擇器錯誤。如果它在課外,我無法獲得數值。它會被我在代碼頂部設置的值覆蓋。我在這裏粘貼所有的代碼。我希望有人能夠幫助我,我對自己無法解決這個問題感到沮喪。不能從一個函數傳遞一個變量到另一個功能斯威夫特

import UIKit 
import MapKit 
import CoreLocation 

class ViewController: UIViewController, UIPickerViewDelegate,  UIPickerViewDataSource, UITextFieldDelegate { 

@IBOutlet weak var dep: UITextField! 

@IBOutlet weak var picker: UIPickerView! 

@IBOutlet weak var arrivesAt: UIButton! 

@IBOutlet weak var departsFrom: UIButton! 

@IBOutlet weak var arr: UITextField! 

@IBOutlet weak var countDownLabel: UILabel! 



var pickerData: [[String]] = [[String]]() 

var timer: NSTimer! 

var count = 2 

var arrayTimes = [""] 


override func viewDidLoad() { 
    super.viewDidLoad() 


    calculateTime().refreshView(["5:45", "6:35", "7:00", "7:30", "7:50", "8:20", "8:40", "9:15", "10:10", "11:10", "12:40", "14:15", "14:50", "15:40", "16:10", "17:10", "17:40", "18:40", "19:25", "20:50"]) 

    picker.hidden = true 

    dep.delegate = self 

    dep.resignFirstResponder() 
    arr.resignFirstResponder() 

    //Picker 

    // Connect data: 
    self.picker.delegate = self 
    self.picker.dataSource = self 


    // Input data into the Array: 
    pickerData = [["larkspur", "saulsalito", "san francisco", "fisherman's wharf", "giants stadium", "tiburon", "vallejo", "alameda", "harbor bay", "jack london", "south s.f."], 
     ["san francisco", "saulsalito", "larkspur", "fisherman's wharf", "giants stadium", "tiburon", "vallejo", "alameda", "harbor bay", "jack london", "south s.f."]] 

} 



//Mark - Location Delegate Methods 



struct MyViewState { 
    static var count = 8 
} 



class calculateTime { 

    var timesArray:[String] = [] 

    var timer: NSTimer! 

    var count: Int = 0 

    func refreshView(array: [String]) { 


     let date = NSDate() 
     let calendar = NSCalendar.currentCalendar() 
     let components = calendar.components([.Hour, .Minute], fromDate: date) 
     let hour = components.hour 
     let minutes = components.minute 
     let currentTime = "\(hour)" + ":" + "\(minutes)" 

     self.timesArray = array 

     print(timesArray) 

     // create a method to convert your time to minutes 
     func stringToMinutes(input:String) -> Int { 
      let components = input.componentsSeparatedByString(":") 
      let hour = Int((components.first ?? "0")) ?? 0 
      let minute = Int((components.last ?? "0")) ?? 0 
      return hour*60 + minute 
     } 

     //create an array with the minutes from the original array 
     let timesMinutesArray:[Int] = timesArray.map { stringToMinutes($0) } 

     let dayMinute = stringToMinutes(currentTime) 
     // filter out the times that has already passed 
     let filteredTimesArray = timesMinutesArray.filter{$0 > dayMinute } 

     // get the first time in your array 
     if let firstTime = filteredTimesArray.first { 
      // find its position and extract it from the original array 
      let nextDeparture = timesArray[timesMinutesArray.indexOf(firstTime)!] // "15:40" 


      let userCalendar = NSCalendar.currentCalendar() 


      let dateMakerFormatter = NSDateFormatter() 
      dateMakerFormatter.calendar = userCalendar 
      dateMakerFormatter.dateFormat = "yyyy/MM/dd" 



      // How many hours and minutes between now and the next ferry 

      dateMakerFormatter.dateFormat = "H:mm" 
      let startTime = dateMakerFormatter.dateFromString(currentTime)! 
      let endTime = dateMakerFormatter.dateFromString(nextDeparture)! 
      let hourMinuteComponents: NSCalendarUnit = [.Hour, .Minute] 
      let timeDifference = userCalendar.components(
       hourMinuteComponents, 
       fromDate: startTime, 
       toDate: endTime, 
       options: []) 

      let difference = (timeDifference.hour*60) + (timeDifference.minute) 

      var count = difference 

      print(count) //this returns correctly 


      timer = NSTimer.scheduledTimerWithTimeInterval(1, target: ViewController(), selector: "update", userInfo: nil, repeats: true) 




     } 


    } 

} 


//Picker 

// The number of columns of data 
func numberOfComponentsInPickerView(picker: UIPickerView) -> Int { 
    return 2 
} 

// The number of rows of data 
func pickerView(picker: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 
    return pickerData[component].count 
} 

// The data to return for the row and component (column) that's being passed in 
func pickerView(picker: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { 
    return pickerData[component][row] 
} 


//Show picker wen text field is click in 
func textFieldShouldBeginEditing(textfield: UITextField) -> Bool { 
    dep.resignFirstResponder() 
    arr.resignFirstResponder() 
    self.dep.tintColor = UIColor.clearColor() 
    self.arr.tintColor = UIColor.clearColor() 

    picker.hidden = false 

    return false 

} 

//Make text uneditable 
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { 
    return false 
} 


// Catpure the picker view selection 
func pickerView(picker: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 
    // This method is triggered whenever the user makes a change to the picker selection. 
    // The parameter named row and component represents what was selected. 
    print("/[component][row]") 

    let fromto = pickerData[component][row] 


    print(fromto) 

    if component == 0 { 

     var count = calculateTime().count 

     arr.text = "san francisco" 

     dep.text = pickerData[component][row] 

     calculateTime().refreshView(["5:45", "6:35", "7:00", "7:30", "7:50", "8:20", "8:40", "9:15", "10:10", "11:10", "12:40", "14:15", "14:50", "15:40", "16:10", "17:10", "17:40", "18:40", "19:25", "20:50"]) 

     print("help") 

     self.countDownLabel.text = "\(count)" 

     print(count) 

    } 

    else { 

     dep.text = pickerData[component][row] 
    } 



    picker.hidden = true; 
} 


func pickerView(picker: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView 
{ 
    var pickerLabel = UILabel() 
    pickerLabel.textColor = UIColor(red: CGFloat(41/255.0), green: CGFloat(100/255.0), blue: CGFloat(226/255.0), alpha: CGFloat(1.0)) 
    pickerLabel.text = pickerData[component][row] 
    // pickerLabel.font = UIFont(name: pickerLabel.font.fontName, size: 15) 
    pickerLabel.font = UIFont(name: "Helvetica Neue", size: 20) // In this use your custom font 
    pickerLabel.textAlignment = NSTextAlignment.Center 
    return pickerLabel 
} 
func pickerView(pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat { 
    return 36.0 
} 



func update() { 


    if count == 1{ 
     //self.minutes.text = "minute" 
     print("did change") 
    } 

    if(count > 0) 
    { 
     //countDownLabel.text = String(count--) 

     print(count) 
    } 

    else if (count == 0) 
    { 
     timer.invalidate() 
     print("ended") 
     calculateTime().refreshView(["5:45", "6:35", "7:00", "7:30", "7:50", "8:20", "8:40", "9:15", "10:10", "11:10", "12:40", "14:15", "14:50", "15:40", "16:10", "17:10", "17:40", "18:40", "19:25", "20:50"]) 

    } 



} 

}

+0

有一種普遍的誤解:你寫的任何時間'calculateTime()'或'視圖控制器()'你分別創建類型的品牌新的實例,所有實例是不同的對象。如果你沒有聲明一個屬性來獲取一個實例在封閉方法退出後立即解除分配的實例的強引用。 'calculateTime()'中的'NSTimer'與你的'ViewController'中的'NSTimer'不同。我想鼓勵你閱讀關於類和實例的基礎知識 – vadian

+0

我知道,我已經買了書,閱讀文章,閱讀蘋果文檔,看了幾個小時的在線教程,但我仍然在掙扎。我想理解這一點,但我還沒有找到任何解釋類,實例等的方式,我可以理解它,所以我只是嘗試通過做。 – matarali

回答

0

你應該在文件的最頂端添加計數變量,以便它是所有功能的文件中訪問。這樣你只有一個計數實例,你可以在整個文件的任何地方更新它。即在文件的頂部:

var count : Int = calculateTime().count 

然後,你可以訪問計數爲你

update() 

函數內完成。

如果它們是在不同的類,那麼你就需要創建一個類的實例,或者,在已經通過這個類的一個實例,例如,如果計數A類初始化:

public class A { 
    var count : Int = 0 
} 

如果你想要再從B類訪問變量,你可以做如下:

public class B { 
    var classA : A = A() 

    print("Count : \(classA.count)") 
} 

這將讓您訪問計數,爲您創建了一個實例。或者,在創建類B的實例時,可以在初始化時傳遞類A的相應實例。例如

public class C { 
    var a : A = A() 
    var b : B = B(class : a) 
} 

public class B { 
    var count : Int 

    init(class : A = A()) { 
     count = class.count 
    } 
} 

此外,裸記住,OOP,你可能會想使用getter和setter方法,而不是僅僅露出計數,使計數私有。即

public class A { 
    private var _count = 0 

    var count : Int { 
     get { 
      return _count 
     } 

     set { 
      if newValue != _count { 
       _count = newValue 
      } 
     } 
    } 
} 

public class B { 
    var classA : A = A() 

    classA.count = 2 // Would set the count of class A, for the particular instance you have created as 2 
} 

這也可以讓你訪問變量。另外,如果這對您沒有幫助,請參閱代表&協議,您也可以通過這種方式傳遞變量。

相關問題