1

heyhey,

since a few days I attempt to create the "Material-Design-Chip", but only with half success.

The attempt with the most success I had, is to make a subclass from "Button" (Button is a subclass from UIButton created from cosmicmind in his MaterialDesign-Framework for swift).

For the people who doesn't know I mean with "chips": click here

my examples:

The simple / non-deletable chip

import UIKit
import Material

class ChipButton: Button {
    override func prepare() {
        super.prepare()

        cornerRadiusPreset      = .cornerRadius5
        backgroundColor         = UIColor.lightGray
        titleColor              = Color.darkText.primary
        pulseAnimation          = .none
        contentEdgeInsets       = EdgeInsets(top: 0, left: 12, bottom: 0, right: 12)
        isUserInteractionEnabled = false
        titleLabel?.font        = RobotoFont.regular
        isOpaque                = true
    }
}

and to create this button:

let button = ChipButton()
    button.title = "default chip"

    view.layout(button).height(32).center(offsetY: -150)

The contact-chip / icon-chip

import UIKit
import Material

class ChipIconButton: ChipButton {
    /*override func prepare() {
        super.prepare()

        contentEdgeInsets       = EdgeInsets(top: 0, left: 16, bottom: 0, right: 12)
    }*/

    public convenience init(image: UIImage?, title: String?){
        self.init()
        prepare(with: image, title: title)
    }

    private func prepare(with image: UIImage?, title: String?) {
        self.image = image
        self.title = title

        self.imageView?.backgroundColor = UIColor.darkGray // this works
        self.imageView?.cornerRadiusPreset = .cornerRadius4 // this works
        self.imageView?.tintColor  = Color.black // this doesn't work

        self.imageEdgeInsets    = EdgeInsets(top: 0, left: -8, bottom: 0, right: 12)
        self.titleEdgeInsets    = EdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        self.contentEdgeInsets  = EdgeInsets(top: 0, left: 8, bottom: 0, right: 12)
    }
}

here I want to

  1. resize the UIImageView to the height of the chip (which is 32 points)

    I tried with self.imageView?.frame = CGRect(x: 50, y: 50, width: 32, height: 32) but nothing changed
    
  2. resize the UIImage little bit smaller (to 20 points)

  3. to change the tintColor of the UIImage

    I tryed with self.imageView?.tintColor = Color.black but nothing changed
    

The deletable chip

import UIKit
import Material

class ChipDeleteableButton: ChipButton {

    override func prepare() {
        super.prepare()

        self.image = #imageLiteral(resourceName: "ic_close_white_24px")
        self.title = title

        //self.frame = CGRect(x: 50, y: 50, width: 32, height: 32)
        self.imageView?.backgroundColor = UIColor.darkGray
        self.imageView?.cornerRadiusPreset = .cornerRadius4
        self.imageView?.tintColor  = Color.black

        self.imageEdgeInsets    = EdgeInsets(top: 0, left: self.frame.size.width, bottom: 0, right: 0)
        self.titleEdgeInsets    = EdgeInsets(top: 0, left: 0, bottom: 0, right: self.frame.size.width)
        self.contentEdgeInsets  = EdgeInsets(top: 0, left: 8, bottom: 0, right: 12)
    }
}

here I tried to switch the positions of the label and with imageEdgeInsets and titleEdgeInsets, but self.frame.size.width returns a incorrect width (maybe couse of AutoLayout but i'm not sure)

help

hope that somebody can help me!

ps. I'm little newbe at swift/xcode

2
  • i find out how to solve: > 3. to change the tintColor of the UIImage for any buttontype (except .system-button) its necessary to add .withRenderingMode(.alwaysTemplate) to the img. for example: self.image = UIImage(named: "image-name").withRenderingMode(.alwaysTemplate) Commented Oct 5, 2016 at 8:18
  • UIImage(named: "image-name")?.withRenderingMode(.alwaysTemplate) the question mark is important Commented Oct 5, 2016 at 8:27

1 Answer 1

1

The simple / non-deletable chip

here nothing changed. look at the question.

The contact-chip / icon-chip

import UIKit
import Material

class ChipIconButton: ChipButton {
    public convenience init(image: UIImage?, title: String?){
        self.init()
        prepare(with: image, title: title)
    }

    private func prepare(with image: UIImage?, title: String?) {
        //self.imageView?.frame = CGRect(x: 0, y: 0, width: 60, height: 60)
        let myThumb = image?.resize(toWidth: 20)?.resize(toHeight: 20)
        let shapeView = UIView(frame: CGRect(x: 0, y: 0, width: 32, height: 32))
        shapeView.backgroundColor = UIColor.darkGray
        shapeView.cornerRadiusPreset = .cornerRadius5
        shapeView.zPosition = (self.imageView?.zPosition)! - 1

        self.addSubview(shapeView)


        self.image = myThumb?.withRenderingMode(.alwaysTemplate)
        self.title = title
        self.imageView?.tintColor  = self.backgroundColor
        self.imageEdgeInsets    = EdgeInsets(top: 0, left: -28, bottom: 0, right: 0)
        self.titleEdgeInsets    = EdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        self.contentEdgeInsets  = EdgeInsets(top: 0, left: 20, bottom: 0, right: 12)
    }
}

and the creation-snipped:

open func prepareChipIconButton () {
    let icon: UIImage? = #imageLiteral(resourceName: "ic_close_white_24px")
    let button = ChipIconButton(image: icon, title: "icon chip")
    view.layout(button).height(32).center(offsetY: 0)
}

The deletable chip

import UIKit
import Material

class ChipDeleteableButton: ChipButton {

    override func prepare() {
        super.prepare()

        let img = #imageLiteral(resourceName: "ic_close_white_24px").resize(toHeight:18)?.resize(toWidth: 18)
        let myThumb = img?.withRenderingMode(.alwaysTemplate)

        self.image = myThumb
        self.title = title

        self.imageView?.tintColor  = self.backgroundColor
        self.isUserInteractionEnabled = true

        self.addTarget(self, action: #selector(clickAction), for: .touchUpInside)
        self.imageView?.isUserInteractionEnabled = false
    }

    open func swapLabelWithImage() {
        let rightLableSize = self.titleLabel?.sizeThatFits((self.titleLabel?.frame.size)!)

        self.imageEdgeInsets    = EdgeInsets(top: 0, left: (rightLableSize?.width)! - 4, bottom: 0, right: 0)
        self.titleEdgeInsets    = EdgeInsets(top: 0, left: -54, bottom: 0, right: 0)
        self.contentEdgeInsets  = EdgeInsets(top: 0, left: 20, bottom: 0, right: 4)

        let shapeView = UIView(frame: CGRect(x: self.imageEdgeInsets.left + 19, y: 6, width: 20, height: 20))
        shapeView.backgroundColor = UIColor.darkGray
        shapeView.cornerRadius = shapeView.frame.size.width/2
        shapeView.zPosition = (self.imageView?.zPosition)! - 1
        shapeView.isUserInteractionEnabled = false


        self.addSubview(shapeView)
    }

    internal func clickAction(sender: ChipDeleteableButton) {
        print("do something")
    }
}

and the creation-snipped:

open func prepareChipDeleteableButton () {
    let button = ChipDeleteableButton()
    button.title    = "deleteable chip"
    button.swapLabelWithImage()

    view.layout(button).height(32).center(offsetY: 150)
}

more info:

  • the creation-function r called in my ViewController, in viewWillAppear()
  • why i have a extra-function for my deletable-chip? - because i let AutoLayout do his job and after that i can get the necessary "String-width" of its label with let rightLableSize = self.titleLabel?.sizeThatFits((self.titleLabel?.frame.size)!)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.