2017-02-06 134 views
1

即時嘗試創建一個tableview控制器,其中每個單元格都有一個漸變作爲背景。在UITableViewCell中設置漸變背景

所以我的方法是下面的代碼,它設置正確的顏色,但滾動時顏色顯示爲隨機設置。

我不知道錯誤在哪裏。 textLabels將被正確設置,但顏色不是。

import UIKit 


class ResourceOverViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { 
let reuseIdentifier = "OverViewCell" 
@IBOutlet weak var prototypeCell: UITableViewCell! 
@IBOutlet weak var tableView:UITableView! 
var resourceInMissions:[ResourceInMission] = [ResourceInMission]() 
var whiteRussian:Int64 = Int64() 
var Caipirinha:[String] = [String]() 
var Avails:[CAGradientLayer] = [CAGradientLayer]() 


override func viewDidLoad() { 
    self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: reuseIdentifier) 
    super.viewDidLoad() 

} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

// MARK: - Table view data source 


override func viewWillAppear(_ animated: Bool) { 
      super.viewWillAppear(animated) 
    setView() 

} 


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    // #warning Incomplete implementation, return the number of rows 
    return Caipirinha.count 
} 


func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { 
    print(indexPath) 

    cell.textLabel?.backgroundColor = UIColor.clear 
    cell.textLabel?.isOpaque = true 
    cell.isOpaque = true 

    var gradient = Avails[indexPath.row] 
    gradient.frame = cell.bounds 

    cell.textLabel?.layer.insertSublayer(gradient, at: 0) 

} 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    var cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) 
    cell.textLabel?.text = Caipirinha[indexPath.row] 

    return cell 
} 



func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){ 
    var index: IndexPath = indexPath 
    let cell = tableView.cellForRow(at: indexPath) 
    whiteRussian = resourceInMissions[indexPath.row].getID() 



    guard let vc = UIStoryboard(name:"Main", bundle:nil).instantiateViewController(withIdentifier: "ShowResource") as UIViewController? else { 
     print("Could not instantiate view controller with identifier of type SecondViewController") 
     return 
    } 

    vc.setObjectID(idToTransfer: whiteRussian) 
    present(vc, animated:true, completion: nil) 

} 

@IBAction func back(){ 
    //Code is in Extension of UIViewController 
    moveBack() 

} 

func sort(resourceInMissions:[ResourceInMission]) -> [ResourceInMission] { 

    var arrayOfArrays = [[ResourceInMission](), [ResourceInMission](), [ResourceInMission](), [ResourceInMission](), [ResourceInMission](), [ResourceInMission]()] 
    // At first take the availability to sort. 
    // It produces availibility lists 
    for element in resourceInMissions { 


     // gets the index of the avail. from availibilities array 
     // for every avail a new list is made in arraysOfArray 


     if let string = element.getAvailability(){ 
      if let av = availibilitys.index(of: string){ 

       arrayOfArrays[av].append(element) 

      } 
     } 

    } 



    // Now iterate through each list and sort for the resourceType 
    // Idea is: get rsIM from one of the arrays above and put it in a type array for each element 
    // after finishing the avail array merge all type arrays for avail list sorted for types 
    var arraySorted:[ResourceInMission] = [ResourceInMission]() 
    for array in arrayOfArrays { 

     // lists have to be initialized for each loop 
     // otherwise the lists would be merged 
     var type1:[ResourceInMission] = [ResourceInMission]() 
     var type2:[ResourceInMission] = [ResourceInMission]() 
     var type3:[ResourceInMission] = [ResourceInMission]() 
     var type4:[ResourceInMission] = [ResourceInMission]() 
     var type5:[ResourceInMission] = [ResourceInMission]() 
     var type6:[ResourceInMission] = [ResourceInMission]() 
     var type7:[ResourceInMission] = [ResourceInMission]() 
     var type8:[ResourceInMission] = [ResourceInMission]() 

     for element in array { 

      if let id = element.getResourceID(){ 
       if let resource = Resource().getByIdFromDB(id: id){ 
        if let typeID = resource.getResourceTypeID(){ 

         switch typeID { 
         case 1: 
          type1.append(element) 
          break 
         case 2: 
          type2.append(element) 
          break 
         case 3: 
          type3.append(element) 
          break 
         case 4: 
          type4.append(element) 
          break 
         case 5: 
          type5.append(element) 
          break 
         case 6: 
          type6.append(element) 
          break 
         case 7: 
          type7.append(element) 
          break 
         case 8: 
          type8.append(element) 
          break 
         default: 
          break 
         } 
        } 
       } 
      } 
     } 

     arraySorted = arraySorted + type1 + type2 + type3 + type4 + type5 + type6 + type7 + type8 


    } 
    return arraySorted 
} 

func setView(){ 
    var count = 0 


    resourceInMissions = [ResourceInMission]() 
    resourceInMissions = try! ResourceInMission().getOverviewList() 
    count = resourceInMissions.count 


    resourceInMissions = sort(resourceInMissions: resourceInMissions) 

    Caipirinha = [String]() 
    Avails = [CAGradientLayer]() 
    Caipirinha.removeAll() 
    for index in 0 ..< resourceInMissions.count { 
     Caipirinha.append(resourceInMissions[index].toString()) 
     let gradient: CAGradientLayer = CAGradientLayer() 

     if let av = resourceInMissions[index].getAvailability(){ 

      switch av { 
      case availibilitys[0]: 
       //blue 
       let blue = [hexStringToUIColor(hex: "#E5EEFF"), hexStringToUIColor(hex: "#93B7FF"), hexStringToUIColor(hex: "#4F8EFF")] 
       gradient.colors = blue.map { $0.cgColor } 
       Avails.append(gradient) 
       break 
      case availibilitys[1]: 
       //red 
       let red = [hexStringToUIColor(hex: "#FFE5E5"), hexStringToUIColor(hex: "#FF8E8B"), hexStringToUIColor(hex: "#FF4F4F")] 
       gradient.colors = red.map { $0.cgColor } 
       Avails.append(gradient) 
       break 
      case availibilitys[2]: 
       //rose 
       let rose = [hexStringToUIColor(hex: "#FFFFFF"), hexStringToUIColor(hex: "#FDEADA"), hexStringToUIColor(hex: "#FAC090")] 
       gradient.colors = rose.map { $0.cgColor } 
       Avails.append(gradient) 
       break 
      case availibilitys[3]: 
       //yellow 
       let yellow = [hexStringToUIColor(hex: "#F5FFE6"), hexStringToUIColor(hex: "#F0FB85"), hexStringToUIColor(hex: "#FBF622")] 
       gradient.colors = yellow.map { $0.cgColor } 
       Avails.append(gradient) 
       break 
      case availibilitys[4]: 
       //green 
       let green = [hexStringToUIColor(hex: "#F5FFE6"), hexStringToUIColor(hex: "#C8FB85"), hexStringToUIColor(hex: "#BCFB5F")] 
       gradient.colors = green.map { $0.cgColor } 
       Avails.append(gradient) 
       break 
      case availibilitys[5]: 
       //grey 
       let gray = [hexStringToUIColor(hex: "#F2F2F2"), hexStringToUIColor(hex: "#E9E9E9"), hexStringToUIColor(hex: "D9D9D9")] 
       gradient.colors = gray.map { $0.cgColor } 
       Avails.append(gradient) 
       break 
      default: 
       break 
      } 
     } 


    } 
    self.tableView.reloadData() 
    } 
}  

回答

0

您的梯度隨機出現的原因是因爲細胞再利用。

cell.textLabel?.layer.insertSublayer(gradient, at: 0) 

此行獲取調用每次你顯示單元格的時間,因此它可以在第一時間但是你的細胞得到重用剛剛進入後面的舊添加新的梯度。

您可以在添加新漸變圖層之前刪除舊的漸變圖層,也可以創建帶有可更新漸變圖層的UITableViewCell子類。

+0

是啊thx。我刪除重複使用,並創建一個新的細胞,每當我需要一個。 效率不高,但適用於我的需求。 – me2

1

你的方法對我來說似乎是錯誤的。

你需要做以下的事情 1)創建一個子類有名稱GradientBackgroundView的UIView並在此視圖 2)在你的故事板的drawRect繪製一個漸變,UITableViewCell中添加到您的tableview中添加GradientBackgroundView作爲背景細胞

希望這將幫助你