NSLayoutConstraint not animating - animation

Everything animates fine from this code except for the mainViewConstraint. I am trying to make the mainView slide in from the top as it appears by transforming the mainViewConstraint coordinate from -195 to 0. Unfortunately, it is not moving from -195 to 0. It just starts to appear at 0.
import UIKit
class FirstViewController: UIViewController {
#IBOutlet weak var bgImage: UIImageView!
#IBOutlet weak var mainView: UIView!
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var findButton: UIButton!
#IBOutlet weak var mainViewConstraint: NSLayoutConstraint!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
mainViewConstraint.constant = -195
for i in [mainView, titleLabel, findButton] {
i?.alpha = 0
}
UIView.animate(withDuration: 1, animations: {
}) { (true) in
self.animateView()
}
}
func animateView() {
UIView.animate(withDuration: 2, animations: {
self.mainView.alpha = 1
self.mainViewConstraint.constant = 0
self.view.layoutIfNeeded()
}) { (true) in
self.animateLbl()
}
}
func animateLbl() {
UIView.animate(withDuration: 1, animations: {
self.titleLabel.alpha = 1
}) { (true) in
self.animateBtn()
}
}
func animateBtn() {
UIView.animate(withDuration: 1) {
self.findButton.alpha = 1
}
}
}

In your code, you're calling animateView() inside an animation block, which seems to be the problem.
Moving it out of the animation block should fix the problem.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
mainViewConstraint.constant = -195
for i in [mainView, titleLabel, findButton] {
i?.alpha = 0
}
self.animateView()
}

To fix this, I changed the location of the mainViewConstraint to -195 in Storyboards and made the following changes to the code:
mainViewConstraint.constant = 0 //-195
for i in [mainView, titleLbl, findBtn] {
i?.alpha = 0
}
UIView.animate(withDuration: 1, animations: {
self.bgImage.alpha = 1
}) { (true) in
self.animateView()
}
}
func animateView() {
UIView.animate(withDuration: 2, animations: {
self.mainView.alpha = 1
//self.mainViewConstraint.constant = 0
self.view.layoutIfNeeded()

Related

How draw a rectangle hole on UIBlurEffect and move it on x axis (UIKit)

I'm trying to create blur effect on a view and than add a shape which will show image on this blurred layer (custom video editing functionality)
Currently I'm able to do it only dragging mask view from the right edge:
but when I try to do it from the left edge, I get such a effect:
func configureBlurView() {
let viewHeight: CGFloat = 60
let padding: CGFloat = 10
blurView = UIView()
blurView.layer.cornerRadius = 10
blurView.clipsToBounds = true
blurView.isHidden = true
blurView.translatesAutoresizingMaskIntoConstraints = false
addSubview(blurView)
addConstraints([
blurView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: padding),
blurView.bottomAnchor.constraint(equalTo: stackView.topAnchor, constant: -padding),
blurView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -padding),
blurView.heightAnchor.constraint(equalToConstant: viewHeight)
])
addBlurEffect(for: blurView)
}
private func addBlurEffect(for view: UIView) {
let blurEffect = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
blurEffect.alpha = 0.5
blurEffect.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(blurEffect)
addConstraints([
blurEffect.topAnchor.constraint(equalTo: view.topAnchor),
blurEffect.leadingAnchor.constraint(equalTo: view.leadingAnchor),
blurEffect.bottomAnchor.constraint(equalTo: view.bottomAnchor),
blurEffect.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
}
private func makeClearHole(rect: CGRect) {
let maskLayer = CAShapeLayer()
maskLayer.fillColor = UIColor.black.cgColor
let pathToOverlay = CGMutablePath()
pathToOverlay.addRect(blurView.bounds)
pathToOverlay.addRect(rect)
maskLayer.path = pathToOverlay
maskLayer.fillRule = .evenOdd
maskLayer.cornerRadius = 10
blurView.layer.mask = maskLayer
}
I'm using touchesMoved method to change orange view dimensions:
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard trimmerView.isHidden == false else { return }
if let touch = touches.first{
let currentTouchPoint = touch.location(in: self)
let previousTouchPoint = touch.previousLocation(in: self)
let deltaX = currentTouchPoint.x - previousTouchPoint.x
if trimmerView.bounds.width >= 70 {
if touchStartEdge.middle {
if trimmerViewLeadingConstraint.constant < 10 {
trimmerViewLeadingConstraint.constant = 10
} else if trimmerViewTrailingConstraint.constant > -10 {
trimmerViewTrailingConstraint.constant = -10
} else {
trimmerViewLeadingConstraint.constant += deltaX
trimmerViewTrailingConstraint.constant += deltaX
}
}
if touchStartEdge.leftEdge {
if trimmerViewLeadingConstraint.constant >= 10.0 {
trimmerViewLeadingConstraint.constant += deltaX
} else if trimmerViewLeadingConstraint.constant < 10.0 {
trimmerViewLeadingConstraint.constant = 10
}
}
if touchStartEdge.rightEdge {
if trimmerViewTrailingConstraint.constant <= -10 {
trimmerViewTrailingConstraint.constant += deltaX
} else if trimmerViewTrailingConstraint.constant > -10 {
trimmerViewTrailingConstraint.constant = -10.0
}
}
}
updateProgressBarConstraints()
makeClearHole(rect: CGRect(x: 0, y: 0, width: trimmerView.frame.width, height: trimmerView.frame.height))
UIView.animate(withDuration: 0.10, delay: 0, options: .curveEaseIn) { [weak self] in
self?.layoutIfNeeded()
}
}
}
What I'd like to achieve is to remove blur effect only in bounds of orange view.
Any ideas ?? :)
Thanks for help!!
Couple ways to do this - here's one...
Add a mask to the blur effect view. As the user drags the "trimmer" update the mask.
Here's a quick example...
We'll:
create a stack view with 10 images
overlay that with a masked blur effective view
add a "draggable trimmer view"
when we drag the trimmer, we update the mask
Example View Controller
class TrimmerVC: UIViewController {
var blurView: MaskedBlurView!
let trimmerView = DragView()
let stackView = UIStackView()
override func viewDidLoad() {
super.viewDidLoad()
// respect safe area when we setup constraints
let g = view.safeAreaLayoutGuide
stackView.distribution = .fillEqually
stackView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(stackView)
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
stackView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0),
stackView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -40.0),
stackView.heightAnchor.constraint(equalToConstant: 80.0),
])
// let's add 10 imageviews to the stack view
for i in 1...10 {
if let img = UIImage(systemName: "\(i).circle.fill") {
let imgView = UIImageView(image: img)
imgView.backgroundColor = UIColor(white: 0.95, alpha: 1.0)
stackView.addArrangedSubview(imgView)
}
}
let blurEffect = UIBlurEffect(style: .dark)
blurView = MaskedBlurView(effect: blurEffect)
blurView.alpha = 0.5
blurView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(blurView)
NSLayoutConstraint.activate([
blurView.topAnchor.constraint(equalTo: stackView.topAnchor, constant: 0.0),
blurView.leadingAnchor.constraint(equalTo: stackView.leadingAnchor, constant: 0.0),
blurView.trailingAnchor.constraint(equalTo: stackView.trailingAnchor, constant: 0.0),
blurView.bottomAnchor.constraint(equalTo: stackView.bottomAnchor, constant: 0.0),
])
trimmerView.backgroundColor = .systemOrange
view.addSubview(trimmerView)
trimmerView.didDrag = { [weak self] newX in
guard let self = self else { return }
self.blurView.clearX = newX - self.stackView.frame.origin.x
}
}
// we'll use this to update the framing when the stack view width changes
// such as on device rotation
var curStackW: CGFloat = -1
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if curStackW != stackView.frame.width {
curStackW = stackView.frame.width
var r = stackView.frame
r.origin.y += r.size.height + 20.0
r.size.width = 160
r.size.height = 40
trimmerView.frame = r
blurView.clearWidth = trimmerView.frame.width
blurView.clearX = 0
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// toggle the trimmer view between
// below the stack view and
// overlaid on the stack view
if trimmerView.frame.origin.y > stackView.frame.origin.y {
let r = stackView.frame
trimmerView.frame.origin.y = r.origin.y - 6.0
trimmerView.frame.size.height = r.height + 12.0
} else {
let r = stackView.frame
trimmerView.frame.origin.y = r.origin.y + r.height + 12.0
trimmerView.frame.size.height = 60.0
}
}
}
Example Draggable "Trimmer" View
class DragView: UIView {
var didDrag: ((CGFloat) -> ())?
let maskLayer = CAShapeLayer()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() {
maskLayer.fillColor = UIColor.red.cgColor
layer.mask = maskLayer
}
override func layoutSubviews() {
super.layoutSubviews()
let pathToOverlay = CGMutablePath()
pathToOverlay.addRect(bounds)
pathToOverlay.addRect(bounds.insetBy(dx: 20.0, dy: 8.0))
maskLayer.path = pathToOverlay
maskLayer.fillRule = .evenOdd
maskLayer.cornerRadius = 10
}
var touchStartX: CGFloat = 0
var frameStartX: CGFloat = 0
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
touchStartX = touch.location(in: self.superview!).x
frameStartX = self.frame.origin.x
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let loc = touch.location(in: self.superview!)
self.frame.origin.x = frameStartX + (loc.x - touchStartX)
didDrag?(self.frame.origin.x)
}
}
Example Masked Blur View
class MaskedBlurView: UIVisualEffectView {
public var clearWidth: CGFloat = 100 {
didSet { updateMask() }
}
public var clearX: CGFloat = 0 {
didSet { updateMask() }
}
private let maskLayer = CAShapeLayer()
override init(effect: UIVisualEffect?) {
super.init(effect: effect)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() {
maskLayer.fillColor = UIColor.red.cgColor
layer.mask = maskLayer
}
func updateMask() {
let leftR = CGRect(x: 0, y: 0, width: clearX, height: bounds.height)
let rightR = CGRect(x: clearX + clearWidth, y: 0, width: bounds.width, height: bounds.height)
let bez = UIBezierPath(rect: leftR)
bez.append(UIBezierPath(rect: rightR))
maskLayer.path = bez.cgPath
}
override func layoutSubviews() {
super.layoutSubviews()
maskLayer.frame = bounds
}
}
When running (in landscape orientation) it will start like this:
I placed the "trimmer" view below the stack view to make it a little more clear what's happening.
As we drag the trimmer view, the blur view's mask will be updated:
Tapping anywhere in an empty part of the screen will toggle the trimmer view between "under the stack view" and "overlaid on the stack view":
This was just put together quickly -- you should have no trouble restructuring the code to wrap everything into a single custom view (or however it would work best for your needs).

Swift 5 & sheetPresentationController passing data

I am learning swift and trying to pass a variable to a sheet but it isn't changing the variable when the sheet pops up, is there a different way to do this?
let bottomSheet = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "bottomSheet")
if let sheet = bottomSheet.sheetPresentationController{
sheet.detents = [.medium()]
sheet.prefersGrabberVisible = true
sheet.preferredCornerRadius = 24
sheet.prefersGrabberVisible = true
}
bottomSheet.isEnabled = true
self.present(bottomSheet, animated: true, completion: nil)
And in the bottomSheet view controller I have the variable
var isEnabled: Bool = false
But even though I put true it always shows as false
Try it like this, what you need to do is specify it as a view controller.
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
if let bottomSheet = mainStoryboard.instantiateViewController(withIdentifier: "bottomSheet") as? BottomSheetVC{
if let sheet = bottomSheet.sheetPresentationController{
sheet.detents = [.medium()]
sheet.prefersGrabberVisible = true
sheet.preferredCornerRadius = 24
sheet.prefersGrabberVisible = true
}
bottomSheet.isEnabled = true
self.present(bottomSheet, animated: true)
}
sheetPresentationController only work for ios 15 and later, for previously versions you need to set .custom modalPresentationStype
controller.modalPresentationStyle = .pageSheet
if #available(iOS 15.0, *) {
if let sheet = controller.sheetPresentationController {
sheet.detents = [.medium()]
}
} else {
controller.modalPresentationStyle = .custom
controller.transitioningDelegate = self
}
self.present(controller, animated: true, completion: nil)
// MARK: - UIViewControllerTransitioningDelegate
extension CPPdfPreviewVC: UIViewControllerTransitioningDelegate {
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
PresentationController(presentedViewController: presented, presenting: presenting)
}
and Add Presentation controller as given
class PresentationController: UIPresentationController {
let blurEffectView: UIVisualEffectView!
var tapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer()
override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) {
let blurEffect = UIBlurEffect(style: .dark)
blurEffectView = UIVisualEffectView(effect: blurEffect)
super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissController))
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.blurEffectView.isUserInteractionEnabled = true
self.blurEffectView.addGestureRecognizer(tapGestureRecognizer)
}
override var frameOfPresentedViewInContainerView: CGRect {
CGRect(origin: CGPoint(x: 0, y: self.containerView!.frame.height * 0.4),
size: CGSize(width: self.containerView!.frame.width, height: self.containerView!.frame.height *
0.6))
}
override func presentationTransitionWillBegin() {
self.blurEffectView.alpha = 0
self.containerView?.addSubview(blurEffectView)
self.presentedViewController.transitionCoordinator?.animate(alongsideTransition: { (UIViewControllerTransitionCoordinatorContext) in
self.blurEffectView.alpha = 0.7
}, completion: { (UIViewControllerTransitionCoordinatorContext) in })
}
override func dismissalTransitionWillBegin() {
self.presentedViewController.transitionCoordinator?.animate(alongsideTransition: { (UIViewControllerTransitionCoordinatorContext) in
self.blurEffectView.alpha = 0
}, completion: { (UIViewControllerTransitionCoordinatorContext) in
self.blurEffectView.removeFromSuperview()
})
}
override func containerViewWillLayoutSubviews() {
super.containerViewWillLayoutSubviews()
presentedView!.roundCorners([.topLeft, .topRight], radius: 22)
}
override func containerViewDidLayoutSubviews() {
super.containerViewDidLayoutSubviews()
presentedView?.frame = frameOfPresentedViewInContainerView
blurEffectView.frame = containerView!.bounds
}
#objc func dismissController(){
self.presentedViewController.dismiss(animated: true, completion: nil)
}
}
extension UIView {
func roundCorners(_ corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners,
cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
layer.mask = mask
}
}
}

Looping Videos with XCode ARKit Image Tracking

Hello I'm new into developing and right now I'm working on an AR application which works with image tracking and it should play different videos on different tracked images.
Right now the video stops, how can I loop the video?
Also if the image is not in the camera view, the video continues. Is there a pause function too?
I would be thankful for every hints.
import UIKit
import SceneKit
import ARKit
class ViewController: UIViewController, ARSCNViewDelegate {
#IBOutlet var sceneView: ARSCNView!
override func viewDidLoad() {
super.viewDidLoad()
sceneView.delegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let configuration = ARImageTrackingConfiguration()
if let trackedImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: Bundle.main) {
configuration.trackingImages = trackedImages
configuration.maximumNumberOfTrackedImages = 2
}
sceneView.session.run(configuration)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
sceneView.session.pause()
}
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
let node = SCNNode()
if let imageAnchor = anchor as? ARImageAnchor {
let size = imageAnchor.referenceImage.physicalSize
var videoNode = SKVideoNode()
switch imageAnchor.name {
case "Image1":
videoNode = SKVideoNode(fileNamed: "Image1.mp4")
case "Image2":
videoNode = SKVideoNode(fileNamed: "Image2.mp4")
case "Image3":
videoNode = SKVideoNode(fileNamed: "Image3.mp4")
default:
break
}
videoNode.play()
let videoScene = SKScene(size: CGSize(width: 1280, height: 960))
videoScene.anchorPoint = CGPoint(x: 0.5, y: 0.5)
videoScene.addChild(videoNode)
let plane = SCNPlane(width: size.width, height: size.height)
plane.firstMaterial?.diffuse.contents = videoScene
let planeNode = SCNNode(geometry: plane)
plane.firstMaterial?.isDoubleSided = true
planeNode.eulerAngles.x = .pi / 2
node.addChildNode(planeNode)
return node
}
return nil
}
}

Swift Infinite Fade in and Out Loop

How can I make a effect in swift similar to this:
I want the animation to loop forever.
For iOS
UIViewAnimationOptions set provides different handy options to achieve a combination of beautiful and complex animations. For your particular scenario you will require two of the options.
UIViewAnimationOptions.Repeat
UIViewAnimationOptions.AutoReverse
Check out the code below for implementation.
Code:
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let view = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
view.backgroundColor = UIColor.blueColor()
self.view.addSubview(view)
UIView.animateWithDuration(1,
delay: 0,
options: [UIViewAnimationOptions.Autoreverse, UIViewAnimationOptions.Repeat],
animations: {
view.backgroundColor = UIColor.clearColor()
},
completion: nil)
}
}
Explanation:
I have created a view with a specific frame for demo purpose.
The part you are interested in is the UIView.animateWithDuration method. Notice that I have provided an array [UIViewAnimationOptions.AutoReverse, UIViewAnimationOptions.Repeat] in the options parameter.
These two options are enough to achieve a smooth and forever looping animation like below.
https://s3.amazonaws.com/uploads.hipchat.com/37040/1764070/6Iow7n7WiWf6Naz/autoReverse.gif
If you don't want to reverse the animation, just remove UIViewAnimationOptions.AutoReverse from the array in the options parameter. You will get an animation like this.
https://s3.amazonaws.com/uploads.hipchat.com/37040/1764070/8fyRUlzqNHSQI47/noreverse.gif
For iOS
let viewSquare be the name of the blue square in your question.
UIView.animate(withDuration: 0.5, delay: 0, options: [.repeat,.autoreverse], animations: {
viewSquare.alpha = 0.0
}, completion: nil)
Swift 5.1
let duration = 0.5
func fadeIn(finished: Bool) {
UIView.animate(withDuration: self.duration, delay: 0,
options: [.curveEaseInOut],
animations: { self.tftMap.alpha = 1 }, completion: self.fadeOut)
}
func fadeOut(finished: Bool) {
UIView.animate(withDuration: self.duration, delay: 0,
options: [.curveEaseInOut],
animations: { self.tftMap.alpha = 0 }, completion: self.fadeIn)
}
I assume you are programming for iOS.
Play around with the duration to see what suits you best:
class ViewController: UIViewController {
#IBOutlet weak var myView: UIView!
let duration = 0.5
override func viewDidLoad() {
super.viewDidLoad()
self.fadeOut(true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func fadeIn(finished: Bool) {
UIView.animateWithDuration(self.duration, delay: 0, options: [.CurveEaseInOut], animations: { self.myView.alpha = 1 } , completion: self.fadeOut)
}
func fadeOut(finished: Bool) {
UIView.animateWithDuration(self.duration, delay: 0, options: [.CurveEaseInOut], animations: { self.myView.alpha = 0 } , completion: self.fadeIn)
}
}
Swift 5
This worked well for me. I wanted to animate a continuous fade in and out of a label, which I placed inside the "cardHeaderView" UIView.
#IBOutlet weak var cardHeaderView: UIView!
Place this inside the "viewDidAppear". I went with a delay of zero so the animation would start right away.
fadeViewInThenOut(view: cardHeaderView, delay: 0)
Here is the function.
func fadeViewInThenOut(view : UIView, delay: TimeInterval) {
let animationDuration = 1.5
UIView.animate(withDuration: animationDuration, delay: delay, options: [UIView.AnimationOptions.autoreverse, UIView.AnimationOptions.repeat], animations: {
view.alpha = 0
}, completion: nil)
}
Swift 5
Fade in 2 seconds
pause 2 seconds,
fade out 2 seconds
Repeat
func startAnimation() {
UIView.animateKeyframes(withDuration: 6.0,
delay: 0,
options: [.repeat, .autoreverse, .calculationModeLinear]) {
UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.165) { [weak self] in
self?.view1.alpha = 0.0
}
UIView.addKeyframe(withRelativeStartTime: 0.165, relativeDuration: 0.165) { [weak self] in
self?.view2.alpha = 1.0
}
UIView.addKeyframe(withRelativeStartTime: 0.66, relativeDuration: 0.165) { [weak self] in
self?.view2.alpha = 0.0
}
ctartTime: 0.825, relativeDuration: 0.165) { [weak self] in
self?.view1.alpha = 1.0
}
}
}
Please note that when your animation is at Alpha == 0.0 the item is not interactable! You will have to add to .allowUserInteraction as an option
If you want repeatable fade animation you can do that by using CABasicAnimation like below :
###First create handy UIView extension :
extension UIView {
enum AnimationKeyPath: String {
case opacity = "opacity"
}
func flash(animation: AnimationKeyPath ,withDuration duration: TimeInterval = 0.5, repeatCount: Float = 5){
let flash = CABasicAnimation(keyPath: AnimationKeyPath.opacity.rawValue)
flash.duration = duration
flash.fromValue = 1 // alpha
flash.toValue = 0 // alpha
flash.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
flash.autoreverses = true
flash.repeatCount = repeatCount
layer.add(flash, forKey: nil)
}
}
###How to use it:
// You can use it with all kind of UIViews e.g. UIButton, UILabel, UIImage, UIImageView, ...
imageView.flash(animation: .opacity, withDuration: 1, repeatCount: 5)
titleLabel.flash(animation: .opacity, withDuration: 1, repeatCount: 5)

Can't change marker icon in MapKit

I did everything on the answer of this link:
Swift different images for Annotation
But the marker icon won't change it just stays the same I tried every way I could find on google but they all give the same result.
This is my code:
import UIKit
import MapKit
class Kaart: UIViewController, MKMapViewDelegate{
#IBOutlet weak var mapView: MKMapView!
let initialLocation = CLLocation(latitude: 52.20614380, longitude: 21.04759094)
let markerLocation = CLLocationCoordinate2D(latitude: 52.20614380, longitude: 21.04759094)
override func viewDidLoad() {
super.viewDidLoad()
UINavigationBar.appearance().translucent = false;
UINavigationBar.appearance().barTintColor = UIColor(red: CGFloat(193.0/255.0), green: 58/255, blue: 44/255, alpha: 1)
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName:UIColor.whiteColor()]
//Set Default location
centerMapOnLocation(initialLocation)
//Place markers
var info1 = CustomPointAnnotation()
info1.coordinate = CLLocationCoordinate2DMake(42, -84)
info1.title = "Info1"
info1.subtitle = "Subtitle"
info1.imageName = "vlag.png"
mapView.addAnnotation(info1)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
let regionRadius: CLLocationDistance = 1000
func centerMapOnLocation(location: CLLocation) {
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate,
regionRadius * 50.0, regionRadius * 50.0)
mapView.setRegion(coordinateRegion, animated: true)
}
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
if !(annotation is CustomPointAnnotation) {
return nil
}
let reuseId = "test"
var anView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
if anView == nil {
anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
anView.canShowCallout = true
}
else {
anView.annotation = annotation
}
//Set annotation-specific properties **AFTER**
//the view is dequeued or created...
let cpa = annotation as! CustomPointAnnotation
anView.image = UIImage(named:cpa.imageName)
return anView
}
}
class CustomPointAnnotation: MKPointAnnotation {
var imageName: String!
}

Resources