UIButton你真的會用嗎峰鄙?

在實際開發(fā)中太雨,經(jīng)常會遇到這幾種圖文排列情況

**上圖下字**
**左圖右字**
**右圖左字**
**上字下圖**

笨笨的我吩翻,第一次接到UI類似上圖下字設(shè)計時狭瞎,毫不猶豫的用了一個UILabelUIImageView的組合,自己覺得很完美葫哗。但是隨著這種設(shè)計的地方越來越多球涛,就產(chǎn)生了很多重復(fù)代碼。

繼續(xù)笨笨的我想到了用個UIView對上面封裝一下捺典,三下五除二完工从祝,代碼有所減少牍陌。

突然有一天,又來了第二種類似左圖右字的設(shè)計贮预。這是我已經(jīng)開始警醒了契讲,隨后將之前用UIView封裝的那個類直接滿足了以上四種情況捡偏。

又過了不久,產(chǎn)品經(jīng)理告訴我你虹,把這個位置(類似上圖下字的地方)加個可以跳轉(zhuǎn)彤避,因為之前用的UIView所以很自然的想到了添加一個手勢忠藤。楼雹。尖阔。

直到有一天介却,我在仿支付寶首頁時块茁,發(fā)現(xiàn)他的最頂上那一欄圖文是一體的(因為點擊圖片和文字都有高亮)数焊。然后上網(wǎng)查了查,原來是UIButton實現(xiàn)的遂蛀。思路干厚,看了這種思路后蛮瞄,默默的回去重構(gòu)了之前的代碼。給UIButton寫了個擴展,大概意思就是把imageEdgeInsets芹助、titleEdgeInsets封裝到一個方法里,支持上面的四種情況闲先,代碼又減少了一點饵蒂,似乎已經(jīng)很完美了。

支付寶效果

就這樣又過了一段時間彼乌。UI給了一套大概這樣的九宮格設(shè)計慰照。

UICollectionView做布局琉朽,縫隙大小不對的同學(xué)可以看這里
FullSizeRender 2.jpg

看了一下箱叁,迅速用 UICollectionView做出主體結(jié)構(gòu)惕医,然后每個cell上面放上UIButton抬伺,調(diào)用封裝的那個方法灾梦。Run一下若河。咦,字和圖片怎么有的是歪的捧灰,歪的统锤,檢查代碼饲窿,沒錯啊。思考一下阀溶,關(guān)于坐標的就只有imageEdgeInsets,titleEdgeInsets

最終確定罪魁禍首是imageEdgeInsets,titleEdgeInsets

至于具體原因還不知道鸦泳,知道的同學(xué)告訴我一下做鹰。

解決

NSLayoutConstraint約束圖片,文字繼續(xù)上面思路就好了(直接設(shè)置frame肯定是不行的)

extension UIButton {

    func set(_ title: String?, with image: UIImage?, direction: NSLayoutAttribute = .top, interval: CGFloat = 10.0) {
        setTitle(title, for: .normal)
        setImage(image, for: .normal)
        guard let titleSize = titleLabel?.bounds.size, let imageSize = imageView?.bounds.size else {
            return
        }
        let horizontal = (frame.width - titleSize.width - imageSize.width - interval) / 2
         let h = imageSize.height + interval
        let vertical = (frame.height - titleSize.height - h) / 2
        imageView?.translatesAutoresizingMaskIntoConstraints = false
        if let constraints = imageView?.superview?.constraints {
            imageView?.superview?.removeConstraints(constraints)
        }
        switch direction {
        case .left, .right:
            let centerY = NSLayoutConstraint(item: imageView!, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0)

            let isRight = direction == .right
            let constraint = NSLayoutConstraint(item: imageView!, attribute: direction, relatedBy: .equal, toItem: self, attribute: direction, multiplier: 1, constant: horizontal * (isRight ? -1 : 1))
            imageView?.superview?.addConstraints([centerY, constraint])

            let offsetX = isRight ? -(0.5 * interval + imageSize.width) * 2 : interval
            titleEdgeInsets = UIEdgeInsets(top: 0, left: offsetX, bottom: 0, right: 0)
        case .bottom, .top:
            let value: CGFloat = direction == .top ? 1 : -1

            let centerX = NSLayoutConstraint(item: imageView!, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0)

            let constraint = NSLayoutConstraint(item: imageView!, attribute: direction, relatedBy: .equal, toItem: self, attribute: direction, multiplier: 1, constant: vertical * value)
            imageView?.superview?.addConstraints([centerX, constraint])

            titleEdgeInsets = UIEdgeInsets(top: h * value, left: -imageSize.width, bottom: 0, right: 0)
        default:
            fatalError("方向不匹配")
        }
    }
}

上面代碼不好理解的應(yīng)該是

let offsetX = isRight ? -(0.5 * interval + imageSize.width) * 2 : interval

在iPhone 5s上打印UIButtontitleLabel饭尝、imageViewframe

屏幕快照 2016-12-08 下午7.06.41.png

假如什么什么也不做实撒,直接設(shè)置title知态、image的效果

屏幕快照 2016-12-08 下午7.08.19.png

結(jié)合上面打印的結(jié)果很容易得出imageViewx坐標

let imageViewX = (frame.width - imageView.frame.width - titleLabel.frame.width) / 2 = 41.25

因為1px=0.5pt肴甸,6p 3px=1pt囚巴,因為像素為最小單位彤叉,不可再分,所以系統(tǒng)取值41

知道以上公式后很容易得出

圖片在左邊浮庐,與文字間距interval(imageView的位置是NSLayoutConstraint約束定死的)

titleEdgeInsets = UIEdgeInsets(top: 0, left: interval, bottom: 0, right: 0)

圖片在右邊审残,與文字間距interval

根據(jù)打印結(jié)果,應(yīng)該得出這個等式
let left =  horizontal - titleLabel.frame.minX
titleEdgeInsets = UIEdgeInsets(top: 0, left: left, bottom: 0, right: 0)

效果是這樣的


屏幕快照 2016-12-08 下午7.30.24.png

計算結(jié)果是肯定沒錯的搅轿,根據(jù)我測量實際剛好差一半富玷,具體原因我也不知道

修改后
let left =  horizontal - titleLabel.frame.minX
titleEdgeInsets = UIEdgeInsets(top: 0, left: left * 2, bottom: 0, right: 0)

但是這里還是有個問題,就是UICollectionViewCell復(fù)用后雀鹃,titleLabel的坐標又不對了黎茎,根據(jù)我打印titleLabel.frame.minX是動態(tài)的

那只有想辦法得出一個靜態(tài)的titleLabel.frame.minX

根據(jù)以上打印結(jié)果当悔,可以推導(dǎo)出
let width =  frame.width - imageView.frame.width - titleLabel.frame.width

titleLabel.frame.minX == width  / 2 + imageView.frame.width // 全是靜態(tài)的

-0.5 * interval - imageSize.width == width / 2 - interval / 2 - titleLabel.frame.minX


titleEdgeInsets = UIEdgeInsets(top: 0, left: -0.5 * interval - imageSize.width, bottom: 0, right: 0)

以上問題完美解決

Demo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末俭正,一起剝皮案震驚了整個濱河市焙畔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌儿惫,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件留搔,死亡現(xiàn)場離奇詭異隔显,居然都是意外死亡饵逐,警方通過查閱死者的電腦和手機倍权,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門薄声,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人生年,你說我怎么就攤上這事廓奕。” “怎么了桌粉?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵蒸绩,是天一觀的道長。 經(jīng)常有香客問我铃肯,道長患亿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任押逼,我火速辦了婚禮步藕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘挑格。我一直安慰自己咙冗,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布雾消。 她就那樣靜靜地躺著灾搏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪立润。 梳的紋絲不亂的頭發(fā)上狂窑,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機與錄音桑腮,去河邊找鬼泉哈。 笑死,一個胖子當(dāng)著我的面吹牛破讨,可吹牛的內(nèi)容都是我干的丛晦。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼添忘,長吁一口氣:“原來是場噩夢啊……” “哼采呐!你這毒婦竟也來了若锁?” 一聲冷哼從身側(cè)響起搁骑,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎又固,沒想到半個月后仲器,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡仰冠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年乏冀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片洋只。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡辆沦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出识虚,到底是詐尸還是另有隱情肢扯,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布担锤,位于F島的核電站蔚晨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏肛循。R本人自食惡果不足惜铭腕,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望多糠。 院中可真熱鬧累舷,春花似錦、人聲如沸夹孔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至害捕,卻和暖如春绿淋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背尝盼。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工吞滞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人盾沫。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓裁赠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親赴精。 傳聞我的和親對象是個殘疾皇子佩捞,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容