How to add the text in UIImageView in Swift? - ios

I have some issues for editing UIImageView. User can enter the text in imageview then it processes to save it and after that user can view this image with the text .
How can I do this?

I tried and got the solution for adding the text inside the UIImageview.Below is the coding
import UIKit
class ViewController: UIViewController,UINavigationControllerDelegate, UIImagePickerControllerDelegate,UIGestureRecognizerDelegate{
#IBOutlet var imageViewText: UIImageView!
var dynamicTextViewInsideImageView : UITextView!
var strImageSelected : String!
var picker = UIImagePickerController()
var xValue = CGFloat()
var yValue = CGFloat()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
imageViewText.layer.cornerRadius = 5
imageViewText.layer.borderColor = UIColor.blueColor().CGColor
imageViewText.layer.borderWidth = 1
strImageSelected = ""
}
override func viewWillAppear(animated: Bool)
{
let tapRecognizer = UITapGestureRecognizer(target: self, action: Selector("imageTapped:"))
//Add the recognizer to your view.
imageViewText.userInteractionEnabled = true
tapRecognizer.numberOfTapsRequired = 1
imageViewText.addGestureRecognizer(tapRecognizer)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func actionPickImage(sender: AnyObject)
{
var alert:UIAlertController=UIAlertController(title: "Choose Image", message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)
var cameraAction = UIAlertAction(title: "Camera", style: UIAlertActionStyle.Default)
{
UIAlertAction in
self.openCamera()
}
var gallaryAction = UIAlertAction(title: "Gallary", style: UIAlertActionStyle.Default)
{
UIAlertAction in
self.openGallary()
}
var cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel)
{
UIAlertAction in
}
// Add the actions
picker.delegate = self
alert.addAction(cameraAction)
alert.addAction(gallaryAction)
alert.addAction(cancelAction)
self.presentViewController(alert, animated: true, completion: nil)
}
func openCamera()
{
if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera))
{
picker.sourceType = UIImagePickerControllerSourceType.Camera
self .presentViewController(picker, animated: true, completion: nil)
}
else
{
let alertWarning = UIAlertView(title:"Warning", message: "You don't have camera", delegate:nil, cancelButtonTitle:"OK", otherButtonTitles:"")
alertWarning.show()
}
}
func openGallary()
{
picker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self.presentViewController(picker, animated: true, completion: nil)
}
//PickerView Delegate Methods
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject])
{
picker .dismissViewControllerAnimated(true, completion: nil)
imageViewText.image=info[UIImagePickerControllerOriginalImage] as? UIImage
strImageSelected = "ImagePicked"
}
func imagePickerControllerDidCancel(picker: UIImagePickerController)
{
println("picker cancel.")
strImageSelected = ""
}
//On the imageView you can add text(Only after you picked the image from Gallery or Camera)
func imageTapped(gestureRecognizer: UITapGestureRecognizer)
{
if strImageSelected.isEmpty{
println("Do not add the textview inside imageview as you have not picked the image from gallery or camera")
}
else
{
println("you picked the image successfully")
dynamicTextViewInsideImageView = UITextView(frame: CGRectMake(xValue,yValue,200,50))
dynamicTextViewInsideImageView.backgroundColor = UIColor( red: 0.9, green: 0.9, blue:0.9, alpha: 1.0 )
imageViewText.addSubview( dynamicTextViewInsideImageView)
}
}
//TouchEvent for Getting X,Y position once we touch inside the imageview
override func touchesBegan(touches: NSSet, withEvent event: UIEvent)
{
if let touch = touches.anyObject() as? UITouch
{
let location = touch.locationInView(imageViewText) as CGPoint
println("the location.x is - \(location.x)")
println("the location.y is - \(location.y)")
xValue = location.x
yValue = location.y
println("the xValue is - \(xValue)")
println("the yValue is - \(yValue)")
}
}
}

Try the following
func waterMarkedImage(waterMarkText:String, corner:WaterMarkCorner = .BottomRight, margin:CGPoint = CGPoint(x: 20, y: 20), waterMarkTextColor:UIColor = UIColor.whiteColor(), waterMarkTextFont:UIFont = UIFont.systemFontOfSize(20), backgroundColor:UIColor = UIColor.clearColor()) -> UIImage{
let textAttributes = [NSForegroundColorAttributeName:waterMarkTextColor, NSFontAttributeName:waterMarkTextFont]
let textSize = NSString(string: waterMarkText).sizeWithAttributes(textAttributes)
var textFrame = CGRectMake(0, 0, textSize.width, textSize.height)
print(textSize.height)
var imageSize = self.size
imageSize = CGSize(width: imageSize.width, height: (imageSize.height+textSize.height))
switch corner{
case .TopLeft:
textFrame.origin = margin
case .TopRight:
textFrame.origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: margin.y)
case .BottomLeft:
textFrame.origin = CGPoint(x: margin.x, y: imageSize.height - textSize.height - margin.y)
case .BottomRight:
textFrame.origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: imageSize.height - textSize.height - margin.y)
case .Center:
textFrame.origin = CGPoint(x: imageSize.width/2 - textSize.width/2, y: imageSize.height - textSize.height - margin.y)
}
/// Start creating the image with water mark
//imageSize = CGSize(width: (imageSize.width+textSize.width), height: (imageSize.height+textSize.height))
UIGraphicsBeginImageContext(imageSize)
self.drawInRect(CGRectMake(0, 0, imageSize.width, imageSize.height - textSize.height))
NSString(string: waterMarkText).drawInRect(textFrame, withAttributes: textAttributes)
let waterMarkedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return waterMarkedImage
}

Related

TextClassification/ Extraction from image How to get single text frame and string Using Core ML from a Image

Need to mark the rec boxes around string and then to get that string after tapping
import UIKit
import Vision
class ViewController: UIViewController, ImageGet {
//MARK: OUTLETS
#IBOutlet weak var selectButton: UIButton!
//MARK: VARIABLES
var objU = UtilityClass()
var image:UIImage?
var str:String?
var uiButton : UIButton?
var arrayString = [String]()
var imageView : UIImageView = UIImageView()
//MARK: DELEGATE FUNCTION
func img(image: UIImage) {
self.image = image
imageView.image = image
setUp()
}
override func viewDidLoad() {
super.viewDidLoad()
imageView.isUserInteractionEnabled = true
// Do any additional setup after loading the view.
}
//MARK: SETUPUI
func setUp() {
let realImg = resizeImage(image: (imageView.image!) , targetSize:CGSize(width: view.frame.width, height: view.frame.height) )
self.image = realImg
self.imageView .image = self.image
imageView.isUserInteractionEnabled = true
self.imageView.frame = CGRect(x: 0, y: 0, width: realImg.size.width, height: realImg.size.height)
view.addSubview(imageView)
guard let cgimg = realImg.cgImage else {return}
let requestHandler = VNImageRequestHandler(cgImage: cgimg)
let req = VNRecognizeTextRequest(completionHandler: recognizeTextHandler)
req.recognitionLevel = .accurate
do {
try requestHandler.perform([req])
} catch {
print("Unable to perform the request: \(error)")
}
}
//MARK: SELECT THE IMAGE
#IBAction func selectButtontapped(_ sender: Any) {
objU.delegate = self
objU.obj = self
objU.ImageGet()
}
func recognizeTextHandler(request : VNRequest , error:Error?) {
guard let observation = request.results as? [VNRecognizedTextObservation], error == nil else {
return
}
_ = observation.compactMap({
$0.topCandidates(1).first?.string
}).joined(separator: "/n")
for subView in imageView.subviews {
subView.removeFromSuperview()
}
let boundingRect :[CGRect] = observation.compactMap{
observation in
guard let candidate = observation.topCandidates(1).first else {return .zero}
//find the bounding box observation
let stringRange = candidate.string.startIndex..<candidate.string.endIndex
let boxObservation = try? candidate.boundingBox(for: stringRange)
let boundingBox = boxObservation?.boundingBox ?? .zero
str = candidate.string
self.arrayString.append(str!)
let rectInImg = VNImageRectForNormalizedRect(boundingBox, Int((imageView.frame.size.width)), Int((imageView.frame.size.height)))
let convertedRect = self.getConvertedRect(boundingBox: observation.boundingBox, inImage:image!.size , containedIn: (imageView.bounds.size))
drawBoundBox(rect: convertedRect)
return rectInImg
}
print(arrayString)
print(boundingRect)
}
func drawBoundBox(rect: CGRect) {
uiButton = UIButton(type: .custom)
uiButton?.frame = rect
uiButton?.layer.borderColor = UIColor.systemPink.cgColor
uiButton?.setTitle("", for: .normal)
uiButton?.layer.borderWidth = 2
uiButton?.tag = arrayString.count
imageView.addSubview(uiButton ?? UIButton())
uiButton?.addTarget(self, action: #selector(pressed(_:)), for: .touchUpInside)
}
#objc func pressed(_ sender : UIButton) {
alert(key: arrayString[sender.tag - 1])
}
//MARK: CONVERT THE NORMALISED BOUNDING RECT
func getConvertedRect(boundingBox: CGRect, inImage imageSize: CGSize, containedIn containerSize: CGSize) -> CGRect {
let rectOfImage: CGRect
let imageAspect = imageSize.width / imageSize.height
let containerAspect = containerSize.width / containerSize.height
if imageAspect > containerAspect { /// image extends left and right
let newImageWidth = containerSize.height * imageAspect /// the width of the overflowing image
let newX = -(newImageWidth - containerSize.width) / 2
rectOfImage = CGRect(x: newX, y: 0, width: newImageWidth, height: containerSize.height)
} else { /// image extends top and bottom
let newImageHeight = containerSize.width * (1 / imageAspect) /// the width of the overflowing image
let newY = -(newImageHeight - containerSize.height) / 2
rectOfImage = CGRect(x: 0, y: newY, width: containerSize.width, height: newImageHeight)
}
let newOriginBoundingBox = CGRect(
x: boundingBox.origin.x,
y: 1 - boundingBox.origin.y - boundingBox.height,
width: boundingBox.width,
height: boundingBox.height
)
var convertedRect = VNImageRectForNormalizedRect(newOriginBoundingBox, Int(rectOfImage.width), Int(rectOfImage.height))
/// add the margins
convertedRect.origin.x += rectOfImage.origin.x
convertedRect.origin.y += rectOfImage.origin.y
return convertedRect
}
//MARK: RESIZE THE IMAGE ACCORD TO DEVICE
func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage {
let size = image.size
let widthRatio = targetSize.width / image.size.width
let heightRatio = targetSize.height / image.size.height
// Figure out what our orientation is, and use that to form the rectangle
var newSize: CGSize
if(widthRatio > heightRatio) {
newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
} else {
newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
}
// This is the rect that we've calculated out and this is what is actually used below
let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
// Actually do the resizing to the rect using the ImageContext stuff
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
image.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
//MARK: POPPING ALERT WITH STRING
func alert(key:String){
let alertController = UIAlertController(title: "String", message: key, preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default) {
(action: UIAlertAction!) in
// Code in this block will trigger when OK button tapped.
}
let copyAction = UIAlertAction(title: "Copy", style: .default) {
(action: UIAlertAction!) in
UIPasteboard.general.string = key
}
alertController.addAction(copyAction)
alertController.addAction(OKAction)
self.present(alertController, animated: true, completion: nil)
}
}

how to make collapsible/expandable views in swift

I created a collapsible/expandable form on android. please see GIF below
https://giphy.com/gifs/zVvcKtgT9QTaa1O29O
I'm trying to create something similar on ios, so far, i've already created the bottom sheet as seen below
Looking at this GIF https://gfycat.com/dismalbronzeblowfish, you'd notice i'm able to expand and collapse the views, but there's a big gap where the view used to be, the expected behavior is that the space collapses also with an animation
Below is the code for the bottom sheet
class BottomSheetViewController: UIViewController {
// holdView can be UIImageView instead
#IBOutlet weak var holdView: UIView!
#IBOutlet weak var left: UIButton!
#IBOutlet weak var right: UIButton!
#IBOutlet weak var pickupView: UIView!
#IBOutlet weak var deliveryView: UIView!
#IBOutlet weak var deliverydetailsView: UIView!
#IBOutlet weak var pickupDetailsVIew: UIControl!
let fullView: CGFloat = 100
var partialView: CGFloat {
return UIScreen.main.bounds.height - 300
}
override func viewDidLoad() {
super.viewDidLoad()
let gesture = UIPanGestureRecognizer.init(target: self, action: #selector(BottomSheetViewController.panGesture))
view.addGestureRecognizer(gesture)
let pickupTapGesture = UITapGestureRecognizer(target: self, action: #selector(pickupButton))
let deliveryTapGesture = UITapGestureRecognizer(target: self, action: #selector(deliveryButton))
pickupView.addGestureRecognizer(pickupTapGesture)
deliveryView.addGestureRecognizer(deliveryTapGesture)
pickupView.setBorder(radius: 5, color: .black)
deliveryView.setBorder(radius: 5, color: .black)
roundViews()
deliverydetailsView.isHidden = true
pickupDetailsVIew.isHidden = true
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
prepareBackgroundView()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIView.animate(withDuration: 0.6, animations: { [weak self] in
let frame = self?.view.frame
let yComponent = self?.partialView
self?.view.frame = CGRect(x: 0, y: yComponent!, width: frame!.width, height: frame!.height)
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func rightButton(_ sender: AnyObject) {
print("clicked")
}
#objc func pickupButton(_ sender: UITapGestureRecognizer) {
print("tap")
if pickupDetailsVIew.isHidden {
expand(pickupDetailsVIew)
collapse(deliverydetailsView)
} else {
collapse(pickupDetailsVIew)
}
}
#objc func deliveryButton(_ sender: UITapGestureRecognizer) {
print("tap")
if deliverydetailsView.isHidden {
expand(deliverydetailsView)
collapse(pickupDetailsVIew)
} else {
collapse(deliverydetailsView)
// if deliveryView.isHidden && pickupDetailsVIew.isHidden {
//
// }
}
}
func expand(_ view: UIView) {
view.isHidden = false
}
func collapse(_ view: UIView) {
view.isHidden = true
}
// #IBAction func close(_ sender: AnyObject) {
// UIView.animate(withDuration: 0.3, animations: {
// let frame = self.view.frame
// self.view.frame = CGRect(x: 0, y: self.partialView, width: frame.width, height: frame.height)
// })
// }
#objc func panGesture(_ recognizer: UIPanGestureRecognizer) {
let translation = recognizer.translation(in: self.view)
let velocity = recognizer.velocity(in: self.view)
let y = self.view.frame.minY
if ( y + translation.y >= fullView) && (y + translation.y <= partialView ) {
self.view.frame = CGRect(x: 0, y: y + translation.y, width: view.frame.width, height: view.frame.height)
recognizer.setTranslation(CGPoint.zero, in: self.view)
}
if recognizer.state == .ended {
var duration = velocity.y < 0 ? Double((y - fullView) / -velocity.y) : Double((partialView - y) / velocity.y )
duration = duration > 1.3 ? 1 : duration
UIView.animate(withDuration: duration, delay: 0.0, options: [.allowUserInteraction], animations: {
if velocity.y >= 0 {
self.view.frame = CGRect(x: 0, y: self.partialView, width: self.view.frame.width, height: self.view.frame.height)
} else {
self.view.frame = CGRect(x: 0, y: self.fullView, width: self.view.frame.width, height: self.view.frame.height)
}
}, completion: nil)
}
}
func roundViews() {
view.layer.cornerRadius = 5
holdView.layer.cornerRadius = 3
// left.layer.cornerRadius = 10
// right.layer.cornerRadius = 10
// left.layer.borderColor = UIColor(red: 0, green: 148/225, blue: 247.0/255.0, alpha: 1).cgColor
// left.layer.borderWidth = 1
view.clipsToBounds = true
}
func prepareBackgroundView(){
// let blurEffect = UIBlurEffect.init(style: .dark)
// let visualEffect = UIVisualEffectView.init(effect: blurEffect)
// let bluredView = UIVisualEffectView.init(effect: blurEffect)
// bluredView.contentView.addSubview(visualEffect)
//
// visualEffect.frame = UIScreen.main.bounds
// bluredView.frame = UIScreen.main.bounds
//
// view.insertSubview(bluredView, at: 0)
}
}
I need some help/pointers in the right direction from anyone who has done this before, or who knows how to do this
Thank you

Drop annotation on virtual map swift3

please help me out.
First time working on a project, with iBeacon involved, which creating Virtual map of inside of a store.
I know how to drop pins, with a MapKit, but how can i do it, if i only have CGPoints on View ?
I managed how to drip UIImage(with pin image), on a view. But when i rotate or pinch, it's not stay on that coordinates that i dropped.
Here's a code :
import UIKit
class MapViewController: UIViewController{
private var scaleView: CGFloat = 1
private var rotateView: CGFloat = 0
private var anchorPoint = CGPoint(x: 0.5, y: 0.5)
private let gestureRecognizerDelegate = GestureRecognizerDelegate()
#IBOutlet weak var mapView: MapView!
#IBOutlet var pinchGestureRecognizer: UIPinchGestureRecognizer!
#IBOutlet var panGestureRecognizer: UIPanGestureRecognizer!
#IBOutlet var rotateGestureRecognizer: UIRotationGestureRecognizer!
#IBOutlet weak var pin: UIImageView!
override func viewDidAppear(_ animated: Bool) {
if !cartIsEmpty {
cartBtn.setImage(UIImage(named: "haveitem"), for: .normal)
} else {
cartBtn.setImage(UIImage(named: "2772"), for: .normal)
}
cartBtn.addTarget(self, action: #selector(openCart), for: .touchUpInside)
let item1 = UIBarButtonItem(customView: cartBtn)
self.navigationItem.rightBarButtonItem = item1
}
override func viewDidDisappear(_ animated: Bool) {
cartBtn.removeTarget(self, action: #selector(openCart), for: .touchUpInside)
}
override func viewDidLoad() {
super.viewDidLoad()
ApplicationManager.sharedInstance.onApplicationStart()
NotificationCenter.default.addObserver(self, selector: #selector(self.onOrientationChanged), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
self.panGestureRecognizer.delegate = gestureRecognizerDelegate
self.pinchGestureRecognizer.delegate = gestureRecognizerDelegate
self.rotateGestureRecognizer.delegate = gestureRecognizerDelegate
ApplicationManager.sharedInstance.gotFloorData = drawFloor
ApplicationManager.sharedInstance.currentUserPoint = drawCurrentUserPoint
}
func drawFloor (floor: Floor) {
mapView.setFloor(currentFloor: floor)
mapView.setNeedsDisplay()
}
func drawCurrentUserPoint(currentUserPoint: CurrentUserLocation, beaconRangingData: [BeaconRangingPoint]) {
mapView.setUserPoint(currentUserPoint: currentUserPoint, beaconRangingData: beaconRangingData)
mapView.setNeedsDisplay()
}
#IBAction func handlePan(recognizer:UIPanGestureRecognizer) {
let translation = recognizer.translation(in: mapView)
if recognizer.view != nil {
let offsetX = translation.x * CGFloat(cosf(Float(rotateView))) - translation.y * CGFloat(sinf(Float(rotateView)))
let offsetY = translation.x * CGFloat(sinf(Float(rotateView))) + translation.y * CGFloat(cosf(Float(rotateView)))
mapView.center = CGPoint(x:mapView.center.x + offsetX * scaleView,
y:mapView.center.y + offsetY * scaleView)
}
recognizer.setTranslation(CGPoint(x: 0, y: 0), in: mapView)
}
#IBAction func handlePinch(recognizer : UIPinchGestureRecognizer) {
if recognizer.view != nil {
setAnchor(point: recognizer.location(in: mapView))
mapView.transform = mapView.transform.scaledBy(x: recognizer.scale, y: recognizer.scale)
scaleView = recognizer.scale * scaleView
recognizer.scale = 1
}
}
#IBAction func handleRotate(recognizer : UIRotationGestureRecognizer) {
if recognizer.view != nil {
setAnchor(point: recognizer.location(in: mapView))
mapView.transform = mapView.transform.rotated(by: recognizer.rotation)
rotateView = rotateView + recognizer.rotation
recognizer.rotation = 0
}
}
private func setAnchor(point : CGPoint) {
let anchor = CGPoint(x: point.x / mapView.bounds.width, y: point.y / mapView.bounds.height)
mapView.layer.anchorPoint = CGPoint(x: anchor.x, y: anchor.y)
let translationX = (mapView.bounds.width * (anchor.x - anchorPoint.x)) * scaleView
let translationY = (mapView.bounds.height * (anchor.y - anchorPoint.y)) * scaleView
let offsetX = translationX * CGFloat(cosf(Float(rotateView))) - translationY * CGFloat(sinf(Float(rotateView)))
let offsetY = translationX * CGFloat(sinf(Float(rotateView))) + translationY * CGFloat(cosf(Float(rotateView)))
mapView.layer.position = CGPoint(x: mapView.layer.position.x + offsetX,
y: mapView.layer.position.y + offsetY)
anchorPoint = anchor
}
private func showAlert(title: String, message: String?, style: UIAlertControllerStyle = .alert) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: style)
let tryAgainAction = UIAlertAction(title: "Try again", style: .default) {
alertAction in
ApplicationManager.sharedInstance.onApplicationStart()
}
let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
alertController.addAction(tryAgainAction)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
func onOrientationChanged() {
self.mapView.setNeedsDisplay()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
also code of mapView:
import UIKit
class MapView: UIView {
private var floor = Floor(walls: [], doors: [], beacons: [])
private let wallColor = UIColor.black
private let doorColor = UIColor.red
private let triangleColor = UIColor.red
private let perpendicularColor = UIColor.darkGray
private let doorLength = 3.0
private let beaconColor = UIColor.green
private let beaconNoActiveColor = UIColor(red: 20/255.0, green: 154.0/255.0, blue: 53.0/255.0, alpha: 1.0)
private let beaconFrameColor = UIColor.brown
private let lineWidthBeaconFrame:CGFloat = 0.25
private let beaconRadius: CGFloat = 5.0
private let userColor = UIColor.blue
private let userFrameColor = UIColor.brown
private let lineWidthUserFrame:CGFloat = 0.25
private let userRadius: CGFloat = 5.0
private let distanceBeaconColor = UIColor.clear
private let distanceBeaconFrameColor = UIColor.green
private let lineWidthOfDistanceFrame: CGFloat = 0.5
private let userRawRadius: CGFloat = 3.0
private let userRawColor = UIColor.darkGray
private let userRawFrameColor = UIColor.lightGray
private let lineWidthOfuserRawFrame: CGFloat = 0.8
private var beaconText: NSString = ""
private let textColor: UIColor = UIColor.red
private let textFont: UIFont = UIFont(name: "Helvetica Neue", size: 5)!
private var currentUserLocation = CurrentUserLocation()
private var beaconRangingData: [BeaconRangingPoint] = []
func setFloor (currentFloor: Floor) {
floor = currentFloor
}
func setUserPoint(currentUserPoint: CurrentUserLocation, beaconRangingData: [BeaconRangingPoint]) {
self.currentUserLocation = currentUserPoint
self.beaconRangingData = beaconRangingData
}
func dropPin(location: CGPoint) {
}
override func draw(_ rect: CGRect) {
let frameToDraw = CoordinatesConverter(boundsWidth: bounds.width, boundsHeight: bounds.height, paddingX: 5, paddingY: 5)
let mapWithScaleCoordinaates = frameToDraw.getSuitableCoordinates(floor: floor, currentUserLocation: currentUserLocation, beaconRangingData: beaconRangingData)
let lines = mapWithScaleCoordinaates.lines
let circles = mapWithScaleCoordinaates.circles
drawLines(lines: lines)
drawCircles(circles: circles)
}
private func drawLines(lines :[Line]) {
let wallPath = UIBezierPath()
let doorPath = UIBezierPath()
let trianglePath = UIBezierPath()
let perpendicularPath = UIBezierPath()
for line in lines {
if line.type == .wall {
wallPath.move(to: CGPoint(x: line.x1, y: line.y1))
wallPath.addLine(to: CGPoint(x: line.x2, y: line.y2))
wallColor.setStroke()
wallPath.stroke()
}
if line.type == .door {
doorPath.move(to: CGPoint(x: line.x1, y: line.y1))
doorPath.addLine(to: CGPoint(x: line.x2, y: line.y2))
doorPath.lineWidth = CGFloat(doorLength)
doorColor.setStroke()
doorPath.stroke()
}
if line.type == .triangle {
trianglePath.move(to: CGPoint(x: line.x1, y: line.y1))
trianglePath.addLine(to: CGPoint(x: line.x2, y: line.y2))
triangleColor.setStroke()
trianglePath.stroke()
}
if line.type == .perpendicular {
perpendicularPath.move(to: CGPoint(x: line.x1, y: line.y1))
perpendicularPath.addLine(to: CGPoint(x: line.x2, y: line.y2))
perpendicularColor.setStroke()
perpendicularPath.stroke()
}
}
}
private func drawCircles(circles: [Circle]) {
let layerViews = layer.sublayers
if layerViews != nil {
for view in layerViews! {
if type(of: view) === CAShapeLayer.self {
view.removeFromSuperlayer()
}
}
}
for circle in circles {
if type(of: circle) === BeaconCircle.self {
if (circle as! BeaconCircle).correctedDistance == 0 {
infoToDrawCircle(circle: circle, radius: beaconRadius, color: beaconNoActiveColor.cgColor, frameColor: beaconFrameColor.cgColor, frameWidth: lineWidthBeaconFrame)
drawBeaconText(circle: circle as! BeaconCircle)
} else {
infoToDrawCircle(circle: circle, radius: beaconRadius, color: beaconColor.cgColor, frameColor: beaconFrameColor.cgColor, frameWidth: lineWidthBeaconFrame)
drawBeaconText(circle: circle as! BeaconCircle)
}
if type(of: circle) === BeaconCircle.self && (circle as! BeaconCircle).correctedDistance != 0 {
infoToDrawCircle(circle: circle, radius: CGFloat((circle as! BeaconCircle).correctedDistance), color: distanceBeaconColor.cgColor, frameColor: distanceBeaconFrameColor.cgColor, frameWidth: lineWidthOfDistanceFrame)
// infoToDrawCircle(circle: circle, radius: CGFloat((circle as! BeaconCircle).notCorrectedDistance), color: UIColor.gray.cgColor, frameColor: distanceBeaconFrameColor.cgColor, frameWidth: lineWidthOfDistanceFrame)
}
} else if type(of: circle) === UserCircle.self {
infoToDrawCircle(circle: circle, radius: userRadius, color: userColor.cgColor, frameColor: userFrameColor.cgColor, frameWidth: lineWidthUserFrame)
} else if type (of: circle) === UserRawCircle.self {
infoToDrawCircle(circle: circle, radius: userRawRadius, color: userRawColor.cgColor, frameColor: userRawFrameColor.cgColor, frameWidth: lineWidthOfuserRawFrame)
} else {
Logger.logMessage(message: "incorrect circle type", level: .error)
break
}
}
}
private func drawBeaconText (circle: BeaconCircle) {
let attributes: NSDictionary = [
NSForegroundColorAttributeName: textColor,
NSFontAttributeName: textFont
]
let minor = circle.minor
let correctDistance = Int(round(100 * circle.correctDistanceForText) / 100)
let notCorrectDistance = Int(round(100 * circle.notCorrectDistanceForText) / 100)
beaconText = "m: \(minor), cd: \(correctDistance), nd: \(notCorrectDistance)" as NSString
if circle.x > Int((bounds.width - 50)) {
beaconText.draw(at: CGPoint(x: circle.x - 70, y: circle.y + 5), withAttributes: attributes as? [String : Any])
} else if circle.x < 20 {
beaconText.draw(at: CGPoint(x: circle.x + 5, y: circle.y + 5), withAttributes: attributes as? [String : Any])
} else {
beaconText.draw(at: CGPoint(x: circle.x + 6, y: circle.y + 5), withAttributes: attributes as? [String : Any])
}
}
private func infoToDrawCircle (circle: Circle, radius: CGFloat, color: CGColor, frameColor: CGColor, frameWidth: CGFloat) {
let center = CGPoint(x: circle.x, y: circle.y)
let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: 0, endAngle: 360, clockwise: true)
let shapeLayer = CAShapeLayer()
shapeLayer.path = path.cgPath
shapeLayer.fillColor = color
shapeLayer.lineWidth = frameWidth
shapeLayer.strokeColor = frameColor
layer.addSublayer(shapeLayer)
}
}
I suggest you conform your MapViewController to the MKMapViewDelegate. In this way you can add annotations (also animated) to the map and you won't have to worry about them anymore since it's all handled by the map delegate.
You can use:
self.map.showAnnotations(pins, animated: true)
where pins is an array of MKAnnotation. Here is the link to the documentation for the method.
Cheers

swift 3 content mode

I have a problem with xcode: I created a draw app where you can draw on the pictures, when I open a picture and I click to draw, the image stretches,
the same thing if I change content mode (aspectFit, aspectFill)
I forget something?
how to set up the content mode correctly?
This is my code:
import UIKit
import Photos
class ViewController: UIViewController {
#IBOutlet var imageView: UIImageView!
#IBOutlet var toolIcon: UIButton!
#IBOutlet var tempImage: UIImageView!
var lastPoint = CGPoint.zero
var swiped = false
var red: CGFloat = 0.0
var green: CGFloat = 0.0
var blue: CGFloat = 0.0
var brushWidth:CGFloat = 10.0
var opacity:CGFloat = 1.0
var tool: UIImageView!
var isDrawing = true
var selectedImage: UIImage!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
imageView.contentMode = UIViewContentMode.scaleAspectFill
tempImage.contentMode = UIViewContentMode.scaleAspectFill
tool = UIImageView()
tool.frame = CGRect(x:self.view.bounds.size.width, y: self.view.bounds.size.height, width: 38, height: 38)
//tool.image = #imageLiteral(resourceName: "Pen")
self.view.addSubview(tool)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?){
swiped = false
if let touch = touches.first {
lastPoint = touch.location(in: self.view)
}
}
func drawLines(fromPoint:CGPoint, toPoint:CGPoint){
UIGraphicsBeginImageContext(self.view.frame.size)
tempImage.image?.draw(in: CGRect(x:0, y:0, width: self.view.frame.width,height: self.view.frame.height))
let context = UIGraphicsGetCurrentContext()
context?.move(to:CGPoint(x:fromPoint.x,y:fromPoint.y))
context?.addLine(to: CGPoint(x:toPoint.x, y: toPoint.y))
tool.center = toPoint
context?.setBlendMode(CGBlendMode.normal)
context?.setLineCap(CGLineCap.round)
context?.setLineWidth(brushWidth)
context?.setStrokeColor(UIColor(red: red, green: green, blue: blue, alpha: 1.0).cgColor)
context?.strokePath()
tempImage.image = UIGraphicsGetImageFromCurrentImageContext()
tempImage.alpha = opacity
UIGraphicsEndImageContext()
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?){
swiped = true
if let touch = touches.first {
let currentPoint = touch.location(in: self.view)
drawLines(fromPoint: lastPoint, toPoint: currentPoint)
lastPoint = currentPoint
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if !swiped {
drawLines(fromPoint: lastPoint, toPoint: lastPoint)
}
// Merge tempImageView into mainImageView
UIGraphicsBeginImageContext(imageView.frame.size)
imageView.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: CGBlendMode.normal, alpha: 1.0)
tempImage.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: CGBlendMode.normal, alpha: opacity)
imageView.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
tempImage.image = nil
}
#IBAction func reset(_ sender: Any) {
self.imageView.image = nil
}
#IBAction func colorPicked(_ sender: UIButton) {
if sender.tag == 0 {
(red,green,blue) = (1,0,0)
}else if sender.tag == 1 {
(red,green,blue) = (0,1,0)
}else if sender.tag == 2{
(red,green,blue) = (0,0,1)
}else if sender.tag == 3 {
(red,green,blue) = (1,0,1)
}else if sender.tag == 4{
(red,green,blue) = (1,1,0)
}else if sender.tag == 5 {
(red,green,blue) = (0,1,1)
}else if sender.tag == 6{
(red,green,blue) = (1,1,1)
}else if sender.tag == 7 {
(red,green,blue) = (0,0,0)
}
}
#IBAction func save(_ sender: Any) {
let actionSheet = UIAlertController(title: "Pick your options", message: "", preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Pick an image", style: .default, handler: { (_) in
let imagePicker = UIImagePickerController()
imagePicker.sourceType = .photoLibrary
imagePicker.allowsEditing = false
imagePicker.delegate = self
self.present(imagePicker, animated: true, completion: nil)
}))
actionSheet.addAction(UIAlertAction(title: "Save your drawing", style: .default, handler: {(_) in
if let image = self.imageView.image {
UIImageWriteToSavedPhotosAlbum(image, nil,nil,nil)
}
}))
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
present(actionSheet, animated: true, completion: nil)
}
#IBAction func erase(_ sender: Any) {
if (isDrawing) {
(red,green,blue) = (1,1,1)
tool.image = #imageLiteral(resourceName: "Gomma")
toolIcon.setImage(#imageLiteral(resourceName: "Pen"), for: .normal)
}else {
(red,green,blue) = (0,0,0)
tool.image = nil
toolIcon.setImage(#imageLiteral(resourceName: "Gomma"), for: .normal)
}
isDrawing = !isDrawing
}
#IBAction func setting(_ sender: Any) {
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
let settingsVc = segue.destination as! SettingViewController
settingsVc.delegate = self
settingsVc.red = red
settingsVc.green = green
settingsVc.blue = blue
settingsVc.brush = brushWidth
settingsVc.opacity = opacity
}
}
extension ViewController:UINavigationControllerDelegate,UIImagePickerControllerDelegate,SettingsVCDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let imagePicked = info[UIImagePickerControllerOriginalImage] as? UIImage {
self.selectedImage = imagePicked
self.imageView.image = selectedImage
self.tempImage.image = selectedImage
dismiss(animated: true, completion: nil)
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
func settingsViewControllerDidFinish(_settingsVc: SettingViewController) {
self.red = _settingsVc.red
self.green = _settingsVc.green
self.blue = _settingsVc.blue
self.brushWidth = _settingsVc.brush
self.opacity = _settingsVc.opacity
}
}

Dissmissed UIViewController didreceivememorywarning - swift

I have a custom UIImagePickerController that still, after being dismissed and the variable set to nil is receiving memory warnings, and it is causing my app to crash because of it.
Here is my UIImagePickerController
import UIKit
import MobileCoreServices
class Picker: UIImagePickerController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var myView = PickerView(frame: UIScreen.mainScreen().bounds)
var takenImages = [UIImage]()
var takenImagesThumbs = [UIImage]()
override init() {
super.init()
myView.picker = self
self.delegate = self
self.sourceType = UIImagePickerControllerSourceType.Camera
self.mediaTypes = [kUTTypeImage]
self.showsCameraControls = false
self.cameraOverlayView = myView
self.cameraCaptureMode = UIImagePickerControllerCameraCaptureMode.Photo
self.setFullscreen()
myView.viewing()
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func setFullscreen(){
let screenSize = UIScreen.mainScreen().bounds.size
let scale = screenSize.height / screenSize.width*3/4
let translate = CGAffineTransformMakeTranslation(0,(screenSize.height - screenSize.width*4/3)*0.5);
let fullScreen = CGAffineTransformMakeScale(scale, scale);
self.cameraViewTransform = CGAffineTransformConcat(fullScreen, translate)
}
var endFunc:((images:[UIImage], thumbs:[UIImage]) -> Void)!
var ViewController:UIViewController!
func show(vc:UIViewController, complete: ((images:[UIImage], thumbs:[UIImage]) -> Void)) {
vc.presentViewController(self, animated: true, completion: nil)
endFunc = complete
ViewController = vc
}
var closeQueue = dispatch_queue_create("areyouareyou", nil)
func close() {
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
dispatch_async(self.closeQueue) {
self.endFunc(images: self.takenImages, thumbs: self.takenImagesThumbs)
self.takenImagesThumbs = [UIImage]()
self.takenImages = [UIImage]()
self.myView.update(self.takenImages.count)
}
}
self.removeFromParentViewController()
self.dismissViewControllerAnimated(true, completion: nil)
}
var resizequeue = dispatch_queue_create("hangingthree", nil)
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
myView.takeButton.enabled = true
let nfo = info as NSDictionary
var image:UIImage = nfo.valueForKey(UIImagePickerControllerOriginalImage) as UIImage
takenImages.append(image)
self.myView.update(self.takenImages.count)
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
dispatch_async(self.resizequeue) {
var theimg = Common.resizeImage(image, scaledToSize: CGSizeMake(UIScreen.mainScreen().bounds.width / 3, UIScreen.mainScreen().bounds.width / 3))
self.takenImagesThumbs.append(theimg)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
println(self.takenImages.count)
}
}
and here is my overlayview
import UIKit
class PickerView: UIView {
var picker:Picker!
var takeButton = UIButton()
var takeButtonPath = UIBezierPath()
var takeButtonLayer = CAShapeLayer()
var takeButtonIconLayer = CAShapeLayer()
var closeButton = UIButton()
var closeButtonBgPath = UIBezierPath()
var closeButtonBgLayer = CAShapeLayer()
var bottomBar:UIVisualEffectView!
var imageCount = UILabel()
override init() {
super.init()
}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func viewing() {
var colors = Colors()
self.backgroundColor = UIColor.clearColor()
imageCount.frame = CGRectMake(62, 0, 30, 31)
imageCount.text = "0"
imageCount.textAlignment = NSTextAlignment.Center
imageCount.font = UIFont(name: "Arial-BoldMT", size: 20)
}
override func drawRect(rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
var colors = Colors()
CGContextSetLineWidth(context, 2)
CGContextSetStrokeColorWithColor(context, colors.pickerStrokeColor.CGColor)
CGContextSetFillColorWithColor(context, colors.pickerFillColor.CGColor)
var point = CGPointMake((self.bounds.width / 2), self.bounds.height - 30)
var start = CGFloat(Common.radians(0))
var end = CGFloat(Common.radians(360))
var moon = UIBezierPath()
moon.addArcWithCenter(point, radius: 45, startAngle: end, endAngle: start, clockwise: true)
moon.stroke()
moon.fill()
var left = UIBezierPath()
left.moveToPoint(CGPointMake(0, point.y))
left.addLineToPoint(CGPointMake(point.x - 45, point.y))
left.stroke()
var right = UIBezierPath()
right.moveToPoint(CGPointMake(self.bounds.width, point.y))
right.addLineToPoint(CGPointMake(point.x + 45, point.y))
right.stroke()
btnCloseing()
btnTakeing()
bottomBaring()
//add
self.addSubview(closeButton)
self.addSubview(takeButton)
}
func bottomBaring() {
var point = CGPointMake((self.bounds.width / 2), self.bounds.height - 30)
var frame = CGRectMake(0, point.y, self.bounds.width, self.bounds.height - point.y)
//blur
var blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Dark)
bottomBar = UIVisualEffectView(effect: blurEffect)
bottomBar.frame = frame
//blur add
self.addSubview(bottomBar)
//vib
var vibEffect = UIVibrancyEffect(forBlurEffect: blurEffect)
var vibView = UIVisualEffectView(effect: vibEffect)
vibView.frame = CGRectMake(0, 0, frame.width, frame.height)
//add
vibView.contentView.addSubview(imageCount)
bottomBar.contentView.addSubview(vibView)
}
func btnCloseing() {
var start = CGFloat(Common.radians(0))
var end = CGFloat(Common.radians(360))
var colors = Colors()
closeButtonBgPath.addArcWithCenter(CGPointMake(0, 0), radius: 20, startAngle: start, endAngle: end, clockwise: true)
closeButtonBgLayer.bounds = CGRectMake(-40, -40, 40, 40)
closeButtonBgLayer.path = closeButtonBgPath.CGPath
closeButtonBgLayer.fillColor = colors.pickerCloseBtnFill.CGColor
closeButtonBgLayer.strokeColor = colors.pickerStrokeColor.CGColor
closeButton.frame = CGRectMake(self.bounds.width - 50, 10, 40, 40)
closeButton.layer.addSublayer(closeButtonBgLayer)
closeButton.setTitle("X", forState: UIControlState.Normal)
closeButton.setTitleColor(colors.pickerStrokeColor, forState: UIControlState.Normal)
closeButton.titleLabel?.font = UIFont(name: "Arial-BoldMT", size: 25)
closeButton.addTarget(self, action: "closePhoto", forControlEvents: UIControlEvents.TouchDown)
}
func btnTakeing() {
var start = CGFloat(Common.radians(0))
var end = CGFloat(Common.radians(360))
var point = CGPointMake((self.bounds.width / 2), self.bounds.height - 30)
takeButtonPath.addArcWithCenter(CGPointMake(0, 0), radius: 40, startAngle: start, endAngle: end, clockwise: true)
takeButtonLayer.bounds = CGRectMake(-80, -90, 80, 80)
takeButtonLayer.path = takeButtonPath.CGPath
takeButtonLayer.fillColor = Colors().pickerTakeBtnFill.CGColor
takeButtonLayer.strokeColor = UIColor.clearColor().CGColor
takeButtonIconLayer.contents = UIImage(named: "CameraIcon")?.CGImage
takeButtonIconLayer.frame = CGRectMake(26, 30, 30, 30)
takeButton.frame = CGRectMake(point.x - 40, point.y - 50, 80, 100)
takeButton.layer.addSublayer(takeButtonLayer)
takeButton.layer.addSublayer(takeButtonIconLayer)
takeButton.addTarget(self, action: "takePhoto", forControlEvents: UIControlEvents.TouchDown)
takeButton.addTarget(self, action: "takePhotoEnd", forControlEvents: UIControlEvents.TouchUpInside)
takeButton.addTarget(self, action: "takePhotoEnd", forControlEvents: UIControlEvents.TouchUpOutside)
}
func takePhoto() {
self.takeButton.enabled = false
takeButtonLayer.fillColor = Colors().pickerTakeBtnFillClick.CGColor
picker.takePicture()
}
func takePhotoEnd() {
takeButtonLayer.fillColor = Colors().pickerTakeBtnFill.CGColor
}
func closePhoto() {
picker.close()
}
func update(count: Int) {
imageCount.text = String(count)
}
}
Anyone knows the problem or how to fix it?
Your problem is that you are subclassing UIImagePickerController which is prohibited. Read the Apple documentation:
IMPORTANT
The UIImagePickerController class supports portrait mode only. This class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified, with one exception. You can assign a custom view to the cameraOverlayView property and use that view to present additional information or manage the interactions between the camera interface and your code.

Resources