0

I have to convert UIView to UIImage because I want to make a custom marker. Currently, I'm making an app using Naver Map SDK. Here is My Code.

let marker = NMFMarker()
marker.position = NMGLatLng(lat: lat, lng: lng)
    
let windowView = CustomInfoWindowView()
windowView.nameLabel.text = name
windowView.jobLabel.text = job
windowView.scoreLabel.text = "\(score)"

marker.iconImage = NMFOverlayImage(image: windowView.asImage())
marker.mapView = mapView

NMFOverlayImage only supported UIImage type.

Here is My full code.

class MapViewController: UIViewController {

   let viewModel = MapViewModel()
   let locations = BehaviorRelay<Void>(value: ())
   let disposedBag = DisposeBag()

   private let imageCell = UIImageView()

   override func viewDidLoad() {
      super.viewDidLoad()
      let mapView = NMFMapView(frame: view.frame)
      view.addSubview(mapView)
    
      bind(mapView: mapView)
   }

   private func bind(mapView: NMFMapView) {
      let input = MapViewModel.Input(getLocations: locations.asSignal(onErrorJustReturn: ()))

      let output = viewModel.transform(input)

      output.getLocations.asObservable().subscribe(onNext: { [unowned self] res in
         if !res.isEmpty {
            for i in 0..<res.count {
                addMarker(
                    lat: res[i].address[1],
                    lng: res[i].address[0],
                    mapView: mapView,
                    name: res[i].name,
                    job: res[i].field,
                    score: res[i].level
                )
            }
        }

     }).disposed(by: disposedBag)

   }

   private func addMarker(lat: Double, lng: Double, mapView: NMFMapView, name: String, job: String, score: Double) {
      let marker = NMFMarker()
      marker.position = NMGLatLng(lat: lat, lng: lng)
    
      let windowView = CustomInfoWindowView()
      windowView.nameLabel.text = name
      windowView.jobLabel.text = job
      windowView.scoreLabel.text = "\(score)"

      marker.iconImage = NMFOverlayImage(image: windowView.asImage())
      marker.mapView = mapView
    }
 }

and this is my custom view code.

import UIKit
import SnapKit
import Then

class CustomInfoWindowView: UIView {

   let customView = UIView().then {
       $0.backgroundColor = .clear
   }

   let windowView = UIView().then {
       $0.backgroundColor = R.color.mainColor()
       $0.layer.cornerRadius = 10
   }

   let marker = UIImageView().then {
       $0.image = R.image.marker()
   }

   let nameLabel = UILabel().then {
       $0.font = .boldSystemFont(ofSize: 16)
       $0.textColor = .white
   }

   let jobLabel = UILabel().then {
       $0.font = .systemFont(ofSize: 12, weight: .medium)
       $0.textColor = R.color.underLine()!
   }

   let starLogo = UIImageView().then {
       $0.image = UIImage(systemName: "star.fill")
       $0.tintColor = .systemYellow
   }

   let scoreLabel = UILabel().then {
       $0.font = .boldSystemFont(ofSize: 14)
       $0.textColor = .white
   }

   override init(frame: CGRect) {
       super.init(frame: frame)
       setUpSubViews()
   }

   required init?(coder: NSCoder) {
       super.init(coder: coder)
   }

   private func setUpSubViews() {
    
       self.addSubview(customView)
    
       [windowView, marker].forEach({customView.addSubview($0)})
    
       [nameLabel, jobLabel, starLogo, scoreLabel].forEach({self.addSubview($0)})
    
       customView.snp.makeConstraints {
           $0.width.equalTo(108)
           $0.height.equalTo(100)
       }
    
       windowView.snp.makeConstraints {
           $0.width.equalToSuperview()
           $0.height.equalTo(64)
           $0.top.equalTo(0)
       }
    
       marker.snp.makeConstraints {
           $0.width.equalTo(20)
           $0.height.equalTo(27)
           $0.top.equalTo(windowView.snp.bottom).offset(10)
           $0.centerX.equalTo(windowView.snp.centerX)
       }
    
       nameLabel.snp.makeConstraints {
           $0.top.leading.equalTo(10)
           $0.width.equalTo(10)
       }
    
       jobLabel.snp.makeConstraints {
           $0.centerY.equalTo(nameLabel.snp.centerY)
           $0.leading.equalTo(nameLabel.snp.trailing).offset(5)
       }
    
       starLogo.snp.makeConstraints {
           $0.top.equalTo(nameLabel.snp.bottom).offset(5)
           $0.leading.equalTo(nameLabel.snp.leading)
           $0.width.height.equalTo(15)
       }
    
       scoreLabel.snp.makeConstraints {
           $0.centerY.equalTo(starLogo.snp.centerY)
           $0.leading.equalTo(starLogo.snp.trailing).offset(3)
       }
   }
}

and this is my UIView Extension code.

extension UIView {
   func asImage() -> UIImage {
       let renderer = UIGraphicsImageRenderer(bounds: bounds)
       return renderer.image { context in
           layer.render(in: context.cgContext)
       }
   }
}

I Use Snapkit, Then, RxSwift, RxCocoa,NMapsMap.

please Help me.

When I run the code .asImage(), It had runtime error. enter image description here

장서영
  • 37
  • 4

0 Answers0