如何在tableview中设置类似集合视图的东西?

时间:2016-01-28 10:03:21

标签: ios swift

以下是我想要实现的一个视觉示例。

sample of the design

我最初的想法是使用带有自定义单元格的UICollectionView,但是效果并不理想,并且在集合视图中尝试收集视图的情况更糟。

所以我尝试在tableview中进行一次收集视图,这种工作方式很有效但是tableviewcell的动态高度被证明是一个巨大的问题,这对我来说非常难以解决,因为我刚开始学习swift和iOS开发。请帮忙:(

修改 请注意,“购物中心1”部分是一个粘性标题。与此类似(绿松石标题):

gif

信用:https://github.com/jamztang/CSStickyHeaderFlowLayout

但我使用https://github.com/petec-blog/CollectionViewStickyHeaders作为例子,因为它更清晰,更接近我的需要。

1 个答案:

答案 0 :(得分:1)

你可以玩下面的代码来获得想法(Xcode 7.2(7C68)) 在Info.plist中删除故事板,启动屏幕,清除属性主故事板和启动屏幕,并将AppDelegate.swift替换为以下内容

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        self.window!.rootViewController = CollectionViewInTableView()
        self.window!.makeKeyAndVisible()
        return true
    }
}

class CollectionViewInTableView: UIViewController, UITableViewDelegate, UITableViewDataSource {
    let table = UITableView()
    override func viewDidLoad() {
        table.delegate = self
        table.dataSource = self
        self.view.backgroundColor = UIColor.whiteColor()
        table.registerClass(Cell.self, forCellReuseIdentifier: Cell.self.description())
        self.view.addSubviewWithConstraints(["v" : table], constraints: ["H:|[v]|", "V:|-50-[v]|"])
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {return 2}
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {return 2}
    func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {return "Shopping Moll \(section)"}

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        return tableView.dequeueReusableCellWithIdentifier(Cell.self.description(), forIndexPath: indexPath) as! Cell
    }

    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {return 200}
}


class Cell: UITableViewCell, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    var collectionView: UICollectionView!

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self.selectionStyle = UITableViewCellSelectionStyle.None


        let layout = UICollectionViewFlowLayout()
        layout.sectionInset = UIEdgeInsets(top: 20, left: 10, bottom: 10, right: 10)
        layout.itemSize = CGSize(width: 75, height: 60)
        layout.headerReferenceSize = CGSize(width: contentView.frame.width, height: 20)

        collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: UIScreen.mainScreen().bounds.width, height: 200), collectionViewLayout: layout)
        collectionView.dataSource = self
        collectionView.delegate = self

        collectionView.registerClass(Item.self, forCellWithReuseIdentifier: Item.self.description())
        collectionView.registerClass(SectionTitle.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: SectionTitle.self.description())
        self.backgroundColor = UIColor.yellowColor()
        collectionView.backgroundColor = UIColor.whiteColor()
        self.contentView.addSubview(collectionView)
    }

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {return 10}

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        return collectionView.dequeueReusableCellWithReuseIdentifier(Item.self.description(), forIndexPath: indexPath) as! Item
    }
    required init?(coder: NSCoder) {super.init(coder: coder)}

    func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
        switch kind {
        case UICollectionElementKindSectionHeader:
            let headerView = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: SectionTitle.self.description(), forIndexPath: indexPath) as! SectionTitle
            headerView.label.text = "Shop \(indexPath.section)"
            return headerView
        default: assert(false, "Unexpected element kind")
        }
    }

}

class SectionTitle: UICollectionReusableView {
    var label: UILabel!
    override init(frame: CGRect) {
        super.init(frame:CGRectZero)
        label = UILabel()
        label.text = "text"
        self.addSubviewWithConstraints(["v" : label], constraints: ["H:|-10-[v]|","V:|[v]|"])
    }

    required init?(coder aDecoder: NSCoder) {fatalError("init(coder:) has not been implemented")}
}


class Item: UICollectionViewCell {
    override init(frame: CGRect) {
        super.init(frame: frame)
        let v = UIView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
        v.backgroundColor = UIColor.blueColor()
        contentView.addSubview(v)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

extension UIView {
    func addSubviewWithConstraints(views: [String : AnyObject], constraints: Array<String>) -> [String : AnyObject] {
        for (_, view) in views {
            self.addSubview(view as! UIView)
            (view as! UIView).translatesAutoresizingMaskIntoConstraints = false
        }
        for var i = 0; i < constraints.count; i++ {self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(constraints[i], options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))}
        return views
    }
}