如何为 iOS 表单使用 Eureka pod 的位置?

Posted

技术标签:

【中文标题】如何为 iOS 表单使用 Eureka pod 的位置?【英文标题】:how to use location for Eureka pod for iOS form? 【发布时间】:2019-05-06 20:04:27 【问题描述】:

我已使用适用于 ios 的 Eureka 表单生成器成功添加了各种文件,但在添加 locationrow 时出现错误

我导入以下框架仍然遇到问题 导入 UIKit 导入核心位置 导入 MapKit 导入尤里卡

还有其他方法可以在 eureka 中使用 locationrow 吗?

【问题讨论】:

【参考方案1】:

您必须首先在您的 pod 文件中添加 LocationRow,然后更新您的 pod 文件,以便 cocoapod 下载 LocationRow。构建项目一次以使用新文件刷新项目。

然后在上面的类中导入LocationRow

【讨论】:

感谢您的回答。但我不确定从/到哪里需要添加 LocationRow。这不是已经包含在 Eureka pod 中了吗?【参考方案2】:

LocationRow(在示例项目中作为自定义行包含)

这些话取自https://github.com/xmartlabs/Eureka

到目前为止,Location Row 无法包含在 Eureka 框架中,因为它需要 MapKit 或类似的东西,这就是为什么 eureka 社区创建了单独的类/对象。

【讨论】:

【参考方案3】:

我为位置代码创建了一个单独的文件夹/文件

import Foundation
import UIKit
import MapKit
import Eureka


//MARK: LocationRow
public final class LocationRow: OptionsRow<PushSelectorCell<CLLocation>>, PresenterRowType, RowType 

public typealias PresenterRow = MapViewController

/// Defines how the view controller will be presented, pushed, etc.
public var presentationMode: PresentationMode<PresenterRow>?

/// Will be called before the presentation occurs.
public var onPresentCallback: ((FormViewController, PresenterRow) -> Void)?

public required init(tag: String?) 
    super.init(tag: tag)
    presentationMode = .show(controllerProvider: ControllerProvider.callback  return MapViewController() _ in  , onDismiss:  vc in _ = vc.navigationController?.popViewController(animated: true) )

    displayValueFor = 
        guard let location = $0 else  return "" 
        let fmt = NumberFormatter()
        fmt.maximumFractionDigits = 4
        fmt.minimumFractionDigits = 4
        let latitude = fmt.string(from: NSNumber(value: location.coordinate.latitude))!
        let longitude = fmt.string(from: NSNumber(value: location.coordinate.longitude))!
        return  "\(latitude), \(longitude)"
    


/**
 Extends `didSelect` method
 */
public override func customDidSelect() 
    super.customDidSelect()
    guard let presentationMode = presentationMode, !isDisabled else  return 
    if let controller = presentationMode.makeController() 
        controller.row = self
        controller.title = selectorTitle ?? controller.title
        onPresentCallback?(cell.formViewController()!, controller)
        presentationMode.present(controller, row: self, presentingController: self.cell.formViewController()!)
     else 
        presentationMode.present(nil, row: self, presentingController: self.cell.formViewController()!)
    


/**
 Prepares the pushed row setting its title and completion callback.
 */
public override func prepare(for segue: UIStoryboardSegue) 
    super.prepare(for: segue)
    guard let rowVC = segue.destination as? PresenterRow else  return 
    rowVC.title = selectorTitle ?? rowVC.title
    rowVC.onDismissCallback = presentationMode?.onDismissCallback ?? rowVC.onDismissCallback
    onPresentCallback?(cell.formViewController()!, rowVC)
    rowVC.row = self



public class MapViewController : UIViewController, TypedRowControllerType, MKMapViewDelegate 

public var row: RowOf<CLLocation>!
public var onDismissCallback: ((UIViewController) -> ())?

lazy var mapView : MKMapView =  [unowned self] in
    let v = MKMapView(frame: self.view.bounds)
    v.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    return v
    ()

lazy var pinView: UIImageView =  [unowned self] in
    let v = UIImageView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
    v.image = UIImage(named: "map_pin", in: Bundle(for: MapViewController.self), compatibleWith: nil)
    v.image = v.image?.withRenderingMode(.alwaysTemplate)
    v.tintColor = self.view.tintColor
    v.backgroundColor = .clear
    v.clipsToBounds = true
    v.contentMode = .scaleAspectFit
    v.isUserInteractionEnabled = false
    return v
    ()

let width: CGFloat = 10.0
let height: CGFloat = 5.0

lazy var ellipse: UIBezierPath =  [unowned self] in
    let ellipse = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: self.width, height: self.height))
    return ellipse
    ()


lazy var ellipsisLayer: CAShapeLayer =  [unowned self] in
    let layer = CAShapeLayer()
    layer.bounds = CGRect(x: 0, y: 0, width: self.width, height: self.height)
    layer.path = self.ellipse.cgPath
    layer.fillColor = UIColor.gray.cgColor
    layer.fillRule = .nonZero
    layer.lineCap = .butt
    layer.lineDashPattern = nil
    layer.lineDashPhase = 0.0
    layer.lineJoin = .miter
    layer.lineWidth = 1.0
    layer.miterLimit = 10.0
    layer.strokeColor = UIColor.gray.cgColor
    return layer
    ()


required public init?(coder aDecoder: NSCoder) 
    super.init(coder: aDecoder)


public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) 
    super.init(nibName: nil, bundle: nil)


convenience public init(_ callback: ((UIViewController) -> ())?)
    self.init(nibName: nil, bundle: nil)
    onDismissCallback = callback


public override func viewDidLoad() 
    super.viewDidLoad()
    view.addSubview(mapView)

    mapView.delegate = self
    mapView.addSubview(pinView)
    mapView.layer.insertSublayer(ellipsisLayer, below: pinView.layer)

    let button = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(MapViewController.tappedDone(_:)))
    button.title = "Done"
    navigationItem.rightBarButtonItem = button

    if let value = row.value 
        let region = MKCoordinateRegion(center: value.coordinate, latitudinalMeters: 400, longitudinalMeters: 400)
        mapView.setRegion(region, animated: true)
    
    else
        mapView.showsUserLocation = true
    
    updateTitle()



public override func viewWillAppear(_ animated: Bool) 
    super.viewWillAppear(animated)

    let center = mapView.convert(mapView.centerCoordinate, toPointTo: pinView)
    pinView.center = CGPoint(x: center.x, y: center.y - (pinView.bounds.height/2))
    ellipsisLayer.position = center



@objc func tappedDone(_ sender: UIBarButtonItem)
    let target = mapView.convert(ellipsisLayer.position, toCoordinateFrom: mapView)
    
    row.value = CLLocation(latitude: target.latitude, longitude: target.longitude)
    onDismissCallback?(self)


func updateTitle()
    let fmt = NumberFormatter()
    fmt.maximumFractionDigits = 4
    fmt.minimumFractionDigits = 4
    let latitude = fmt.string(from: NSNumber(value: mapView.centerCoordinate.latitude))!
    let longitude = fmt.string(from: NSNumber(value: mapView.centerCoordinate.longitude))!
    title = "\(latitude), \(longitude)"
    


public func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) 
    ellipsisLayer.transform = CATransform3DMakeScale(0.5, 0.5, 1)
    UIView.animate(withDuration: 0.2, animations:  [weak self] in
        self?.pinView.center = CGPoint(x: self!.pinView.center.x, y: self!.pinView.center.y - 10)
        )


public func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) 
    ellipsisLayer.transform = CATransform3DIdentity
    UIView.animate(withDuration: 0.2, animations:  [weak self] in
        self?.pinView.center = CGPoint(x: self!.pinView.center.x, y: self!.pinView.center.y + 10)
        )
    updateTitle()


在我的表单中,我刚刚添加了一个这样的新行:

<<< LocationRow("Location")
        $0.title = $0.tag
        $0.value = CLLocation(latitude: -34.9124, longitude: -56.1594)
    

这也是一个很好的资源。 https://fluttergeek.com/blog/eureka-locationrow/

【讨论】:

以上是关于如何为 iOS 表单使用 Eureka pod 的位置?的主要内容,如果未能解决你的问题,请参考以下文章

如何为容器设置正确的cpu millicores?

eureka ios表单更改背景颜色

如何为表单选择做可访问的内联错误?

如何为谷歌表单等字段设计数据库?

Angular Material Mat-Stepper:如何为多个步骤使用相同的表单组?

如何为查询中的条件使用变量以将查询限制为活动表单?