Swift UITableView每隔10个细胞显示不同的细胞

时间:2017-11-28 19:17:55

标签: arrays swift tableview cell

我试图在使用两个数组的每10个单元格后显示不同的单元格:“ads”和“requests” 我希望我的TableView看起来像这样:

"Request"
"Request"
"Request"
"Request"
"Request"
"Request"
"Request"
"Request"
"Request"
"Request"
"Ad"
"Request"
"Request"
...

我知道如何制作广告但不知道如何使用两个数组来订购这样的单元格。一点也不 :/ 任何建议如何实现?提前谢谢!

编辑:

func loadAds()
    {
        Api.adApi.observeAds
        {
            (ad) in
            self.list = self.requests
            for i in stride(from: self.adInterval, to: self.requests.count, by: self.adInterval).reversed()
            {
                // not getting executed
                print("test1")
                self.list.insert(ad, at: i)
            }
            // getting executed
            print("test2")
        }
    }

3 个答案:

答案 0 :(得分:3)

cellForRowAt中,只需检查if indexPath.row % 10 == 0即可。如果确实如此,那么你就是10的倍数。然后你需要做的就是实例化一个差异单元格。您还需要跟踪请求数据阵列和广告数据阵列的索引。你可以这样做。

class MyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    var requestIndex = 0
    var adIndex = 0

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if indexPath.row % 10 != 0 || indexPath.row == 0 {
            requestIndex += 1
            let cell = tableView.dequeueReusableCell(withIdentifier: "RequestCell", for: indexPath) as! RequestCell
            // configure cell with requestIndex
            // cell.imageView.image = requestDataArray[requestIndex].image
            return cell
        }
        else {
            let cell = tableView.dequeueReusableCell(withIdentifier: "AdCell", for: indexPath) as! AdCell
            adIndex += 1
            // configure cell with adIndex
            // cell.imageView.image = adDataArray[adIndex].image
            return cell
    }
}

您还可以使用一些基本的数学来跟踪指数

if indexPath.row % 10 != 0 {
    let requestIndex = indexPath.row - (indexPath.row / 10) // current indexPath - the number of adds already displayed
}
else {
    let adIndex = (indexPath.row / 10) + 1 // number of previously displayed ads plus one
}

答案 1 :(得分:1)

有两种基本方法:

  1. 其中一个(由他人描述)是拥有两个数组并让UITableViewDataSource方法根据indexPath.row % 10找出要出列的单元格。

    这里的问题,恕我直言,你最终会在数据源方法中使用丑陋的逻辑,将indexPath.row映射到响应数组或广告数组中的相应行。

    因此,我建议实用程序函数dataRowadRow对相关数组中的索引进行反向工程(如果nil则返回IndexPath并非相关):

    extension ViewController: UITableViewDataSource {
    
        private func dataRow(for indexPath: IndexPath) -> Int? {
            let (quotient, remainder) = (indexPath.row + 1).quotientAndRemainder(dividingBy: adInterval)
            if remainder == 0 { return nil }
            return quotient * (adInterval - 1) + remainder - 1
        }
    
        private func adRow(for indexPath: IndexPath) -> Int? {
            let (quotient, remainder) = (indexPath.row + 1).quotientAndRemainder(dividingBy: adInterval)
            if remainder != 0 { return nil }
            return quotient - 1
        }
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return objects.count + ads.count
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            if let row = dataRow(for: indexPath) {
                let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath)
                let object = objects[row]
                // configure cell using model data, `object`
                return cell
            } else if let row = adRow(for: indexPath) {
                let cell = tableView.dequeueReusableCell(withIdentifier: "AdCell", for: indexPath)
                let ad = ads[row]
                // configure cell using ad data, `ad`
                return cell
            }
    
            fatalError("Did not find data or ad for cell: Should never get here")
        }
    
    }
    
    顺便说一句,请注意我不仅仅是indexPath.row % 10(因为我不希望第一件事显示为广告)。所以我实际上在做(indexPath.row + 1) % 10

  2. 另一种方法是使用单一视图模型结构来代表模型对象和广告的整合列表。例如,假设我的列表和广告中的项目都有模型对象:

    protocol Listable { }
    
    /// An Item is a model object for "real" objects to be shown in table 
    
    struct Item: Listable {
        let string: String
        let imageURL: URL
    }
    
    /// An Ad is a model object for advertisement to be inserted into table
    
    struct Ad: Listable {
        let string: String
    }
    

    然后,根据我的项目列表,我可以插入我的广告,构建项目和广告的综合列表:

    var items: [Item]! = ...
    var list: [Listable]!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        // build consolidated list of items and ads
    
        list = items
        for i in stride(from: adInterval, to: items.count, by: adInterval).reversed() {
            list.insert(Ad(...), at: i)
        }
    }
    

    然后UITableViewDataSource方法不需要做任何数学计算来确定特定列表的数组,而只是看看它是哪种类型并采取相应的行动:

    extension ViewController: UITableViewDataSource {
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return list.count
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let listing = list[indexPath.row]
    
            if let item = listing as? Item {
                let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath)
                // configure cell using `item`
                return cell
            } else if let ad = listing as? Ad {
                let cell = tableView.dequeueReusableCell(withIdentifier: "AdCell", for: indexPath)
                // configure cell using `ad`
                return cell
            }
    
            fatalError("Did not find data or ad for cell: Should never get here")
        }
    
    }
    

答案 2 :(得分:0)

尝试使用会重复的单个广告,但这会花费您的数组[index%10]值不会显示

server:
  ports:
      - "8761:8761"
eureka:
  client:
    registerWithEureka: false
    fetchRegistry: false

如果我们有多个广告,我们可以在每个第n个值的模型数组中插入广告,并添加额外的属性,例如containsAds,这样我们就像这样检查

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if indexPath.row % 10 == 0 {

    //return ads cell
    }
    else{
    //normal cell
    }


    }

因此整个操作是通过按特定顺序插入广告来修改原始数组