1. 程式人生 > >Swift版仿天貓搜尋介面

Swift版仿天貓搜尋介面

最近在逛天貓,發現天貓的搜尋框還不錯,於是就決定動手實現一下這個介面,按照我的習慣首先是分析這個介面,然後構思實現的技術點,之後再動手寫程式碼。

先上效果圖:


分析:

1:仔細看了看天貓的整體介面,我的想法是分為兩個view,上面一個view裝按鈕、搜尋框,下面一個view就是裝一個可以滾動的ScrollView,看這種佈局,所以ScrollView上面放一個CollectView(具有九宮格樣式),好了,大致的控制元件摸清楚了,如何實現呢!不要急,一步步來

2:第一步分析整體介面,我用的xib佈局整個介面,既然用到了xib,想要載入資料就得註冊cell和定義Layout,而“猜你所想”和“最近搜尋”是CollectView中的兩個組頭,所以想打好第一步,把該做的都搭好

   
        //設定佈局
       collectionView.setCollectionViewLayout(XYSearchLayout(), animated: true)
        
       //載入cell
       collectionView.registerNib(UINib(nibName: "XYSearchCell", bundle: nil), forCellWithReuseIdentifier: "XYSearchCell")

       //載入cell的頭部
        collectionView.registerNib(UINib(nibName: "XYReusableView",  bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader , withReuseIdentifier:"XYReusableView")

3:它主要是分兩組,第一組是一開始就載入”猜你所想“資料,當然這組資料應該是請求獲取到的,而第二組資料是搜尋時才會加載出來,也就是說只有使用者進行搜尋了才會顯示第二組資料(當然使用者搜尋的也就成為了歷史資料,儲存下來),所以在搜尋控制元件代理方法中獲取到輸入的內容然後直接新增到陣列中,重新整理

4:CollectView的佈局利用系統的無法達到想要的效果,這裡使用自定義佈局。計算每個cell的位置

主要程式碼:

  //這裡就是返回每個cell,通過這裡來調整位置
    override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
       let arrCell =  super.layoutAttributesForElementsInRect(rect)
        for(var i = 1 ; i < arrCell?.count ; ++i){
            //當前 UICollectionViewLayoutAttributes
             let currentLayout = arrCell![i]
            //上一個 UICollectionViewLayoutAttributes
            let prevLayout = arrCell![i - 1]
            //前後兩個cell屬於同一個組的時候
            if (prevLayout.indexPath.section == currentLayout.indexPath.section) {
                //我們想設定的最大間距,可根據需要改
                let maximumSpacing = 15
                //前一個cell的最右邊
                let origin = CGRectGetMaxX(prevLayout.frame);
                //如果當前一個cell的最右邊加上我們想要的間距加上當前cell的寬度依然在contentSize中,我們改變當前cell的原點位置
                //不加這個判斷的後果是,UICollectionView只顯示一行,原因是下面所有cell的x值都被加到第一行最後一個元素的後面了
                if((CGFloat(origin) + CGFloat(maximumSpacing) + currentLayout.frame.size.width) < self.collectionViewContentSize().width) {
                    //就是兩個cell之間的間距是maximumSpacing
                    var frame = currentLayout.frame
                    frame.origin.x = CGFloat(origin) + CGFloat(maximumSpacing)
                    currentLayout.frame = frame
                }
            }
        }
        return arrCell
   
    }
5:當然每個cell的大小也得計算,但是我們不能直接寫死,因為每個cell的寬是根據文字的大小來合理設定的,所以這裡我們又得實現返回每個item的Size代理方法。

程式碼:

  //MARK - UICollectionViewDelegateFlowLayout  itme的大小  根據itme大小決定一行顯示多少
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
      
        let seacrhModel =  plistArr[indexPath.section] as? XYSearchModel
        if(seacrhModel?.content?.count > 0){
            
         let itemModel =  seacrhModel?.content![indexPath.row] as? XYItemModel
          //顯示的內容
         let text = itemModel!.name! as NSString
         let size = text.boundingRectWithSize(CGSizeMake(CGFloat(MAXFLOAT), 24), options: .UsesLineFragmentOrigin, attributes: [NSFontAttributeName:UIFont.systemFontOfSize(12)], context: nil).size
           return CGSizeMake(size.width+20, 24)
        }
        
        return CGSizeMake(80, 24)

    }

總結:主要的幾個關鍵點差不多就是這些,其餘的一些細節就得自己思考來寫了,按照思路每一步慢慢實現,就能完成這個功能點。

程式碼地址