1

I have a custom cell for my UITableView. If the user chose a picture for an item cell will show a picture: enter image description here

if not, I will show first two characters of the item name: enter image description here

I'm using following code from paint code to make rectangle:

public class CircleStyleKit : NSObject {

    //// Drawing Methods

    public dynamic class func drawCanvas1(frame targetFrame: CGRect = CGRect(x: 0, y: 0, width: 38, height: 38), resizing: ResizingBehavior = .aspectFit, circleLable: String = "DR", circleSize: CGSize = CGSize(width: 38, height: 38), textSize: CGFloat = 17) {
        //// General Declarations
        let context = UIGraphicsGetCurrentContext()!

        //// Resize to Target Frame
        context.saveGState()
        let resizedFrame: CGRect = resizing.apply(rect: CGRect(x: 0, y: 0, width: 38, height: 38), target: targetFrame)
        context.translateBy(x: resizedFrame.minX, y: resizedFrame.minY)
        context.scaleBy(x: resizedFrame.width / 38, y: resizedFrame.height / 38)
} // It's too long 

I showed part of code because it's too long.

Then I used a UIView to draw this rectangle:

import UIKit

class CirclyStyleView: UIView {

    override func draw(_ rect: CGRect) {
       CircleStyleKit.drawCanvas1()
        }

    }

}

There are two problems:

First, if I use UIImageView in my storyboard I just can draw an image and I don't know if I can draw a rectangle with my code or not. However, I checked it doesn't work.

Second if I use UIView, I can draw a rectangle, but if I want to draw an image I should use UIColor(patternImage: UIImage(named: "picName")!), but I can't change this image frame the way I did for image view. For example, make it circle as I've shown in the picture.

The question is, can I use UIImageView and is there any way to make my rectangle in UIImageView Or can I use UIView and is there any way to set my custom image. I mean change image size and frame.

Amir Movahedi
  • 1,802
  • 3
  • 29
  • 52

1 Answers1

3

Use a single UIImageView and create a method on your model that returns a UIImage given it's circumstances. When an image must be drawn, draw into an "image context".

I'm not a swift author, so in almost-swift...

func imageForThisItem(item : AnyObject) -> UIImage {
    // not really "AnyObject", use the object type in your data source array
    // even better, make this a method on that model object 

    if (/* item has an image, like the sailboat */) {
        return UIImage(named:"SailboatImage")  // or however you got the sailboat image
    } else {
        // initialize "size" to be the same size as the sailboat images
        UIGraphicsBeginImageContextWithOptions(size, false, 0)

        // do your circle and text drawing here within the rect (0,0,size.width,size.height)
        UIColor.greenColor().setFill()
        let bezier = UIBezierPath(rect : rect)
        bezier.fill()

        let initials = item.initials() // however you get this
        // even better, if this is a model method, then self.initials()

        let attributes = // an attribute dictionary, see link below
        initials.drawInRect(rect, withAttributes: attributes)
        // or use CGOffsetRect to provide a little margin

        var image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

Here's an example of text attributes in swift.

Another great reason to make this a method on your model is that you should probably cache the result of this method so you don't have to compute it each time. The lazy initializer pattern is perfect for this.

lazy var imageForThisItem: [UIImage] = {
    // code as above, using "self" rather than item
}()
Community
  • 1
  • 1
danh
  • 62,181
  • 10
  • 95
  • 136