MapView in a VC and its Searchbar in another - swift3

As per the title, in general I'd like to show, in one VC, a MapView and in a second VC a SearchBar (using another TableVC to display, as the user types, "GeoElements" obtained by MKLocalSearchRequest). This because I want to display in the Map some AnnotationViews with custom Callouts. My problem is that the TableVC doesn't update with placemarks as the user types in the SearchBar..
MAPVIEW code:
import UIKit
import MapKit
protocol HandleMapSearch {
func dropPinZoomIn(placemark:MKPlacemark)
}
class ViewController: UIViewController {
#IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
var selectedPin:MKPlacemark? = nil
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
locationManager.requestWhenInUseAuthorization()
locationManager.requestLocation()
}
func getDirections(){
if let selectedPin = selectedPin {
let mapItem = MKMapItem(placemark: selectedPin)
let launchOptions = [MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving]
mapItem.openInMaps(launchOptions: launchOptions)
}
}
}
extension ViewController : CLLocationManagerDelegate {
private func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
if status == .authorizedWhenInUse {
locationManager.requestLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.first {
let span = MKCoordinateSpanMake(0.05, 0.05)
let region = MKCoordinateRegion(center: location.coordinate, span: span)
mapView.setRegion(region, animated: true)
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("error:: (error)")
}
}
extension ViewController: HandleMapSearch {
func dropPinZoomIn(placemark:MKPlacemark){
// cache the pin
selectedPin = placemark
let annotation = MKPointAnnotation()
annotation.coordinate = placemark.coordinate
annotation.title = placemark.name
if let city = placemark.locality,
let state = placemark.administrativeArea {
annotation.subtitle = "(city) (state)"
}
mapView.addAnnotation(annotation)
let span = MKCoordinateSpanMake(0.05, 0.05)
let region = MKCoordinateRegionMake(placemark.coordinate, span)
mapView.setRegion(region, animated: true)
}
}
extension ViewController : MKMapViewDelegate {
func mapView(_: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?{
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView?.pinTintColor = UIColor.orange
pinView?.canShowCallout = true
let smallSquare = CGSize(width: 30, height: 30)
let button = UIButton(frame: CGRect(origin: CGPoint(x: 0,y :0), size: smallSquare))
button.setBackgroundImage(UIImage(named: "car"), for: .normal)
button.addTarget(self, action: Selector(("getDirections")), for: .touchUpInside)
pinView?.leftCalloutAccessoryView = button
return pinView
}
}
EVENT code:
import UIKit
import MapKit
class EventVC: UIViewController {
var resultSearchController:UISearchController? = nil
override func viewDidLoad() {
super.viewDidLoad()
let locationSearchTable = storyboard!.instantiateViewController(withIdentifier: "LocationSearchTable") as! LocationSearchTable
resultSearchController = UISearchController(searchResultsController: locationSearchTable)
resultSearchController?.searchResultsUpdater = locationSearchTable
let searchBar = resultSearchController!.searchBar
searchBar.sizeToFit()
searchBar.placeholder = "Insert Address"
navigationItem.titleView = resultSearchController?.searchBar
resultSearchController?.hidesNavigationBarDuringPresentation = false
resultSearchController?.dimsBackgroundDuringPresentation = true
definesPresentationContext = true
//these two below are problematic
locationSearchTable.mapView = mapView
locationSearchTable.handleMapSearchDelegate = self
}
}
LOCATIONSEARCHTABLE code:
import UIKit
import MapKit
class LocationSearchTable: UITableViewController {
var matchingItems:[MKMapItem] = []
var mapView: MKMapView? = nil
var handleMapSearchDelegate:HandleMapSearch? = nil
override func viewDidLoad() {
super.viewDidLoad()
}
func parseAddress(selectedItem:MKPlacemark) -> String {
// put a space between "4" and "Melrose Place"
let firstSpace = (selectedItem.subThoroughfare != nil && selectedItem.thoroughfare != nil) ? " " : ""
// put a comma between street and city/state
let comma = (selectedItem.subThoroughfare != nil || selectedItem.thoroughfare != nil) && (selectedItem.subAdministrativeArea != nil || selectedItem.administrativeArea != nil) ? ", " : ""
// put a space between "Washington" and "DC"
let secondSpace = (selectedItem.subAdministrativeArea != nil && selectedItem.administrativeArea != nil) ? " " : ""
let addressLine = String(
format:"%#%#%#%#%#%#%#",
// street number
selectedItem.subThoroughfare ?? "",
firstSpace,
// street name
selectedItem.thoroughfare ?? "",
comma,
// city
selectedItem.locality ?? "",
secondSpace,
// state
selectedItem.administrativeArea ?? ""
)
return addressLine
}
}
extension LocationSearchTable : UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController){
guard let mapView = mapView,
let searchBarText = searchController.searchBar.text else { return }
let request = MKLocalSearchRequest()
request.naturalLanguageQuery = searchBarText
request.region = mapView.region
let search = MKLocalSearch(request: request)
search.start { response, _ in
guard let response = response else {
return
}
self.matchingItems = response.mapItems
self.tableView.reloadData()
}
}
}
extension LocationSearchTable {
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return matchingItems.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
let selectedItem = matchingItems[indexPath.row].placemark
cell.textLabel?.text = selectedItem.name
cell.detailTextLabel?.text = parseAddress(selectedItem: selectedItem)
return cell
}
}

Related

SwiftUI: Highlighting Text with different colors using WkWebView

I am trying to use swiftUI to be able to create a custom EPUB reader. Ive looked around at some but none fit my needs. I want to be able to customize it. The issue I have ran into is being able to Highlight text while reading either Orange, blue, green, etc. When highlight a text and then the menu bar pops up and I click on my custom MenuBar color the app crashes. I found this article on highlighting text but uses the UIkit and not SwiftUI. Ive been trying to "translate"(not sure what the correct term is)it to use it with SwiftUI but crashes due to unrecognized selector.Im thinking I am not setting up the things correct. Not sure if it is worth using SwiftUI anymore and just switching my app to UIKit at this point since I have not been able to find many resources using swiftUI. Here is article to highlight text : https://dailong.medium.com/highlight-text-in-wkwebview-1659a19715e6
Just started learning swiftUI so not sure if the way the WebView is setup is correct.
Here is the gitHub link to all of the code https://github.com/longvudai/demo/tree/master/highlight-webview/highlight-webview With the SwiftUI all i did was copy and paste the files. Only difference is with SwiftUI was wrapping the WebView other than that everything else is the same.
SWIFTUI
`struct WebView: UIViewRepresentable {
class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
var webView: CustomView?
var serializedObject: SerializedObject?
private var dataStack = Stack<Highlights>()
func webView(_ webView: WKWebView?, didFinish navigation: WKNavigation!) {
self.webView = webView as? CustomView
}
// receive message from wkwebview
func userContentController(
_ userContentController: WKUserContentController,
didReceive message: WKScriptMessage
) {
if let markerHandler = MarkerScript.Handler(message) {
guard
let dataString = message.body as? String,
let data = dataString.data(using: .utf8)
else { return }
let decoder = JSONDecoder()
guard let serialized = try? decoder.decode(
SerializedObject.self,
from: data
) else { return }
receiveMarkerMessage(markerHandler, data: serialized)
}
}
func receiveMarkerMessage(_ handler: MarkerScript.Handler, data: SerializedObject) {
switch handler {
case .serialize:
serializedObject = data
// your callback here
let script = MarkerScript.Evaluate.clearSelection()
self.webView?.evaluateJavaScript(script)
case .erase:
serializedObject = data
let highlights = data.highlights
let listId = highlights.map { $0.id }
guard let top = dataStack.top else { return }
let newData = top.filter { listId.contains($0.id) }
if newData != top {
dataStack.push(newData)
}
}
}
func highlight(_ color: MarkerColor) {
let script =
MarkerScript.Evaluate.highlightSelectedTextWithColor(color)
webView?.evaluateJavaScript(script)
print("highlightfunction")
}
func removeAll() {
let script = MarkerScript.Evaluate.removeAllHighlights()
self.webView?.evaluateJavaScript(script)
dataStack.push([])
}
func erase() {
let script = MarkerScript.Evaluate.erase()
self.webView?.evaluateJavaScript(script)
}
#objc func highlightthiscolor() {
highlight(MarkerColor.orange)
}
}
func makeCoordinator() -> Coordinator {
return Coordinator()
}
func makeUIView(context: Context) -> CustomView {
let coordinator = makeCoordinator()
let configuration = WKWebViewConfiguration()
let uc = configuration.userContentController
uc.addUserScript(WKUserScript.injectViewPort())
// Jquery
uc.addUserScript(JQueryScript.core())
// Rangy
uc.addUserScript(RangyScript.core())
uc.addUserScript(RangyScript.classapplier())
uc.addUserScript(RangyScript.highlighter())
uc.addUserScript(RangyScript.selectionsaverestore())
uc.addUserScript(RangyScript.textrange())
// Marker
uc.addUserScript(MarkerScript.css())
uc.addUserScript(MarkerScript.jsScript())
uc.add(coordinator, name: MarkerScript.Handler.serialize.rawValue)
uc.add(coordinator, name: MarkerScript.Handler.erase.rawValue)
let _wkwebview = CustomView(frame: .zero, configuration: configuration)
_wkwebview.navigationDelegate = coordinator
return _wkwebview
}
func updateUIView(_ webView: CustomView, context: Context) {
guard let path: String = Bundle.main.path(forResource: "sample", ofType: "html") else { return }
let localHTMLUrl = URL(fileURLWithPath: path, isDirectory: false)
webView.loadFileURL(localHTMLUrl, allowingReadAccessTo: localHTMLUrl)
addCustomContextMenu()
}
func addCustomContextMenu(){
//Has to be type of WKWebView
let colorOrange:UIMenuItem = UIMenuItem(title: "Orange", action: #selector(Coordinator.highlightthiscolor))
UIMenuController.shared.menuItems = [colorOrange]
}
}`
UIKit
protocol MarkerLogic {
func erase()
func highlight(_ color: MarkerColor)
func removeAll()
}
class Marker: NSObject {
weak var webView: WKWebView?
var serializedObject: SerializedObject?
private var dataStack = Stack<Highlights>()
}
extension Marker: MarkerLogic {
func highlight(_ color: MarkerColor) {
let script =
MarkerScript.Evaluate.highlightSelectedTextWithColor(color)
webView?.evaluateJavaScript(script)
}
func removeAll() {
let script = MarkerScript.Evaluate.removeAllHighlights()
webView?.evaluateJavaScript(script)
dataStack.push([])
}
func erase() {
let script = MarkerScript.Evaluate.erase()
webView?.evaluateJavaScript(script)
}
}
// MARK: - WKScriptMessageHandler
extension Marker: WKScriptMessageHandler {
func userContentController(
_ userContentController: WKUserContentController,
didReceive message: WKScriptMessage
) {
if let markerHandler = MarkerScript.Handler(message) {
guard
let dataString = message.body as? String,
let data = dataString.data(using: .utf8)
else { return }
let decoder = JSONDecoder()
guard let serialized = try? decoder.decode(
SerializedObject.self,
from: data
) else { return }
receiveMarkerMessage(markerHandler, data: serialized)
}
}
func receiveMarkerMessage(_ handler: MarkerScript.Handler, data: SerializedObject) {
switch handler {
case .serialize:
serializedObject = data
// your callback here
let script = MarkerScript.Evaluate.clearSelection()
webView?.evaluateJavaScript(script)
case .erase:
serializedObject = data
let highlights = data.highlights
let listId = highlights.map { $0.id }
guard let top = dataStack.top else { return }
let newData = top.filter { listId.contains($0.id) }
if newData != top {
dataStack.push(newData)
}
}
}
}
--- ViewDidLoad
class ViewController: UIViewController, WKScriptMessageHandler {
let marker: Marker = Marker()
let orangeButton: UIButton = {
let v = UIButton()
v.tag = 0
v.backgroundColor = MarkerColor.orange.value
v.layer.cornerRadius = 10
v.addTarget(self, action: #selector(highlight(_:)), for: .touchUpInside)
return v
}()
let cyanButton: UIButton = {
let v = UIButton()
v.tag = 1
v.backgroundColor = MarkerColor.cyan.value
v.layer.cornerRadius = 10
v.addTarget(self, action: #selector(highlight(_:)), for: .touchUpInside)
return v
}()
let pinkButton: UIButton = {
let v = UIButton()
v.tag = 2
v.backgroundColor = MarkerColor.pink.value
v.layer.cornerRadius = 10
v.addTarget(self, action: #selector(highlight(_:)), for: .touchUpInside)
return v
}()
let eraseButton: UIButton = {
let v = UIButton()
v.setTitle("Erase", for: .normal)
v.setTitleColor(.systemBlue, for: .normal)
v.addTarget(self, action: #selector(erase), for: .touchUpInside)
return v
}()
let eraseAllButton: UIButton = {
let v = UIButton(type: .close)
v.addTarget(self, action: #selector(eraseAll), for: .touchUpInside)
return v
}()
lazy var toolBars: UIStackView = {
let v = UIStackView(arrangedSubviews: [orangeButton, cyanButton, pinkButton, eraseButton, eraseAllButton])
v.axis = .horizontal
v.distribution = .fillEqually
v.spacing = 20
return v
}()
// This is to make the makeUIView
lazy var webView: WKWebView = {
let config = WKWebViewConfiguration()
let uc = config.userContentController
uc.addUserScript(WKUserScript.injectViewPort())
// Jquery
uc.addUserScript(JQueryScript.core())
// Rangy
uc.addUserScript(RangyScript.core())
uc.addUserScript(RangyScript.classapplier())
uc.addUserScript(RangyScript.highlighter())
uc.addUserScript(RangyScript.selectionsaverestore())
uc.addUserScript(RangyScript.textrange())
// Marker
uc.addUserScript(MarkerScript.css())
uc.addUserScript(MarkerScript.jsScript())
uc.add(self.marker, name: MarkerScript.Handler.serialize.rawValue)
uc.add(self.marker, name: MarkerScript.Handler.erase.rawValue)
let v = WKWebView(frame: .zero, configuration: config)
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
marker.webView = webView
let path = Bundle.main.path(forResource: "sample", ofType: "html")!
let url = URL(fileURLWithPath: path)
webView.loadFileURL(url, allowingReadAccessTo: url)
let views = [webView, toolBars]
views.forEach {
view.addSubview($0)
$0.translatesAutoresizingMaskIntoConstraints = false
}
NSLayoutConstraint.activate([
webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 40),
webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
toolBars.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
toolBars.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
toolBars.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
toolBars.heightAnchor.constraint(equalToConstant: 40)
])
}
// MARK: - Selector
#objc func highlight(_ sender: UIButton) {
switch sender.tag {
case 0:
marker.highlight(MarkerColor.orange)
case 1:
marker.highlight(MarkerColor.cyan)
case 2:
marker.highlight(MarkerColor.pink)
default:
break
}
}
#objc func erase() {
marker.erase()
}
#objc func eraseAll() {
marker.removeAll()
}
// MARK: - WKScriptMessageHandler
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
}
}
I was finally able to get the code working by looking at the post: Call evaluateJavascript from a SwiftUI button. The problem I was running into was the fact that I was not able to run the javascript func in order to highlight. Using Combine i was able to make a button in the View and when that button is clicked being able to run the javascript code. Will post the code below for anyone who is interested.
import WebKit
import SwiftUI
import Combine
class WebViewData: ObservableObject {
#Published var parsedText: NSAttributedString? = nil
var functionCaller = PassthroughSubject<Void,Never>()
var isInit = false
var shouldUpdateView = true
}
struct ContentView: View {
#StateObject var webViewData = WebViewData()
var body: some View {
VStack {
Button(action: {
webViewData.functionCaller.send()
}) {
Text("Orange")
}
WebView(data: webViewData)
}
}
}
struct WebView: UIViewRepresentable {
#StateObject var data: WebViewData
class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
//var webView: WKWebView?
var serializedObject: SerializedObject?
private var dataStack = Stack<Highlights>()
var parent: WebView
var webView: WKWebView? = nil
private var cancellable : AnyCancellable?
init(view: WebView) {
self.parent = view
super.init()
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.webView = webView
}
// receive message from wkwebview
func userContentController(
_ userContentController: WKUserContentController,
didReceive message: WKScriptMessage
) {
if let markerHandler = MarkerScript.Handler(message) {
guard
let dataString = message.body as? String,
let data = dataString.data(using: .utf8)
else { return }
let decoder = JSONDecoder()
guard let serialized = try? decoder.decode(
SerializedObject.self,
from: data
) else { return }
receiveMarkerMessage(markerHandler, data: serialized)
}
}
func receiveMarkerMessage(_ handler: MarkerScript.Handler, data: SerializedObject) {
switch handler {
case .serialize:
serializedObject = data
// your callback here
let script = MarkerScript.Evaluate.clearSelection()
self.webView?.evaluateJavaScript(script)
case .erase:
serializedObject = data
let highlights = data.highlights
let listId = highlights.map { $0.id }
guard let top = dataStack.top else { return }
let newData = top.filter { listId.contains($0.id) }
if newData != top {
dataStack.push(newData)
}
}
}
func tieFunctionCaller(data: WebViewData) {
cancellable = data.functionCaller.sink(receiveValue: { _ in
self.webView?.evaluateJavaScript("highlightSelectedTextWithColor('orange')")
})
}
}
func makeCoordinator() -> Coordinator {
return Coordinator(view: self)
}
func makeUIView(context: Context) -> WKWebView {
let coordinator = makeCoordinator()
let configuration = WKWebViewConfiguration()
let uc = configuration.userContentController
uc.addUserScript(WKUserScript.injectViewPort())
// Jquery
uc.addUserScript(JQueryScript.core())
// Rangy
uc.addUserScript(RangyScript.core())
uc.addUserScript(RangyScript.classapplier())
uc.addUserScript(RangyScript.highlighter())
uc.addUserScript(RangyScript.selectionsaverestore())
uc.addUserScript(RangyScript.textrange())
// Marker
uc.addUserScript(MarkerScript.css())
uc.addUserScript(MarkerScript.jsScript())
uc.add(coordinator, name: MarkerScript.Handler.serialize.rawValue)
uc.add(coordinator, name: MarkerScript.Handler.erase.rawValue)
let _wkwebview = WKWebView(frame: .zero, configuration: configuration)
_wkwebview.navigationDelegate = coordinator
return _wkwebview
}
func updateUIView(_ webView: WKWebView, context: Context) {
guard data.shouldUpdateView else {
data.shouldUpdateView = false
return
}
context.coordinator.tieFunctionCaller(data: data)
context.coordinator.webView = webView
guard let path: String = Bundle.main.path(forResource: "sample", ofType: "html") else { return }
let localHTMLUrl = URL(fileURLWithPath: path, isDirectory: false)
webView.loadFileURL(localHTMLUrl, allowingReadAccessTo: localHTMLUrl)
}
}

Image capture from camera and gallery in swift

I am trying to get image from camera and show in imageview using swift 3.0 but it is showing white background only. Image is uploaded to my server successfully. On iPAD it is not even opening the camera app. below is my code: I am new to swift to please let me know what mistake i ma doing.
import UIKit
import Alamofire
import SwiftyJSON
import AlamofireImage
class RadiologyViewController:UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate,UITextViewDelegate{
#IBOutlet weak var indicator1: UIActivityIndicatorView!
#IBOutlet weak var name : UILabel!
#IBOutlet weak var mobile: UILabel!
#IBOutlet weak var gender: UILabel!
#IBOutlet weak var age : UILabel!
#IBOutlet weak var indicator4: UIActivityIndicatorView!
#IBOutlet weak var indicator3: UIActivityIndicatorView!
#IBOutlet weak var indicator2: UIActivityIndicatorView!
#IBOutlet weak var pic4text: UITextView!
#IBOutlet weak var pic3text: UITextView!
#IBOutlet weak var pic2text: UITextView!
#IBOutlet weak var pictext1: UITextView!
// WHICH SHOW BUTTON YOU WANT TO SHOW YOU HAVE TO CHANGE HEIGHT CONSTRAINT //
// conPic1height = conPic1height - 20 - UN HIDE BUTTON BY TAKING ITS OUTLET//
#IBOutlet weak var conPic1height: NSLayoutConstraint!
#IBOutlet weak var conPic2height: NSLayoutConstraint!
#IBOutlet weak var conPic3height: NSLayoutConstraint!
#IBOutlet weak var conPic4height: NSLayoutConstraint!
#IBOutlet weak var pic4: UIImageView!
#IBOutlet weak var pic3: UIImageView!
#IBOutlet weak var pic2: UIImageView!
#IBOutlet weak var pic1: UIImageView!
#IBOutlet weak var complain: UILabel!
#IBOutlet weak var explain : UILabel!
#IBOutlet weak var date : UILabel!
#IBOutlet weak var btnShowPic4: UIButton!
#IBOutlet weak var btnShowPic3: UIButton!
#IBOutlet weak var btnShowPic2: UIButton!
#IBOutlet weak var btnShowPic1: UIButton!
var patient : Patients? = nil;
var username : String? = nil;
var picNumber : Int = 0;
var pic1path : String = "";
var pic2path : String = "";
var pic3path : String = "";
var pic4path : String = "";
var strLabel = UILabel()
var indicator = UIActivityIndicatorView()
let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.isNavigationBarHidden = true
if patient != nil {
name.text = patient?.patientName;
age.text = "Age: "+(patient?.patientAge)!;
gender.text = "Gender: "+(patient?.patientGender)!;
mobile.text = "Mobile: "+(patient?.patientMobile)!;
date.text = "Date: "+(patient?.patientDate)!;
complain.text = "Complaint: " + "\(self.makeComplainText(complain: (patient?.patientComplaint)!))";
explain.text = "Explain: "+(patient?.patientExplainComplaint)!;
}
let defaults1 = UserDefaults.standard
let user = defaults1.object(forKey: "user") as? NSData
let responseData = NSKeyedUnarchiver.unarchiveObject(with: user! as Data) as? ResponseModel
if responseData != nil {
if responseData?.profile != nil {
username = responseData?.profile[0].userName;
}
}
pictext1.delegate = self
pic2text.delegate = self
pic3text.delegate = self
pic4text.delegate = self
pic1path = (patient?.patientPic1)!;
pic2path = (patient?.patientPic2)!;
pic3path = (patient?.patientPic3)!;
pic4path = (patient?.patientPic4)!;
pictext1.text = patient?.patientPictxt1;
pic2text.text = patient?.patientPictxt2;
pic3text.text = patient?.patientPictxt3;
pic4text.text = patient?.patientPictxt4;
let tapFirstGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped1(_:)))
pic1.isUserInteractionEnabled = true
pic1.addGestureRecognizer(tapFirstGestureRecognizer)
let tapSecondGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped2(_:)))
pic2.isUserInteractionEnabled = true
pic2.addGestureRecognizer(tapSecondGestureRecognizer)
let tapThirdGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped3(_:)))
pic3.isUserInteractionEnabled = true
pic3.addGestureRecognizer(tapThirdGestureRecognizer)
let tapFourGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped4(_:)))
pic4.isUserInteractionEnabled = true
pic4.addGestureRecognizer(tapFourGestureRecognizer)
if patient?.patientPic1 != "" {
pic1.image = nil;
setImage(imageview: pic1, url: (patient?.patientPic1)!,indicator:indicator1)
showFirstButton(show: false)
} else {
showFirstButton(show: true)
indicator1.isHidden = true
}
if patient?.patientPic2 != "" {
pic2.image = nil;
showSecondButton(show: false)
setImage(imageview: pic2, url: (patient?.patientPic2)!,indicator:indicator2)
} else {
showSecondButton(show: true)
indicator2.isHidden = true
}
if patient?.patientPic3 != "" {
pic3.image = nil;
showThreeButton(show: false)
setImage(imageview: pic3, url: (patient?.patientPic3)!,indicator:indicator3)
} else {
showThreeButton(show: true)
indicator3.isHidden = true
}
if patient?.patientPic4 != "" {
pic4.image = nil;
showFourButton(show: false)
setImage(imageview: pic4, url: (patient?.patientPic4)!,indicator:indicator4)
} else {
showFourButton(show: true)
indicator4.isHidden = true
}
let tapKeuboardDismissGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard(_:)))
view.isUserInteractionEnabled = true
view.addGestureRecognizer(tapKeuboardDismissGestureRecognizer)
// Do any additional setup after loading the view.
}
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == "\n" // Recognizes enter key in keyboard
{
textView.resignFirstResponder()
return false
}
return true
}
func dismissKeyboard(_ sender: UITapGestureRecognizer) {
view.endEditing(true)
}
func imageTapped1(_ sender: UITapGestureRecognizer) {
if (sender.view as? UIImageView) != nil {
print("Image Tapped")
picNumber = 1;
showActionSheet()
}
}
func imageTapped2(_ sender: UITapGestureRecognizer) {
if (sender.view as? UIImageView) != nil {
print("Image Tapped")
picNumber = 2;
showActionSheet()
}
}
func imageTapped3(_ sender: UITapGestureRecognizer) {
if (sender.view as? UIImageView) != nil {
print("Image Tapped")
picNumber = 3;
showActionSheet()
}
}
func imageTapped4(_ sender: UITapGestureRecognizer) {
if (sender.view as? UIImageView) != nil {
print("Image Tapped")
picNumber = 4;
showActionSheet()
}
}
func camera()
{
let myPickerController = UIImagePickerController()
myPickerController.delegate = self;
myPickerController.allowsEditing = false
myPickerController.sourceType = UIImagePickerControllerSourceType.camera
myPickerController.cameraCaptureMode = .photo
myPickerController.modalPresentationStyle = .fullScreen
self.present(myPickerController, animated: true, completion: nil)
}
func photoLibrary()
{
let myPickerController = UIImagePickerController()
myPickerController.delegate = self;
myPickerController.sourceType = UIImagePickerControllerSourceType.photoLibrary
self.present(myPickerController, animated: true, completion: nil)
}
func showActionSheet() {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertControllerStyle.actionSheet)
actionSheet.addAction(UIAlertAction(title: "Camera", style: UIAlertActionStyle.default, handler: { (alert:UIAlertAction!) -> Void in
self.camera()
}))
actionSheet.addAction(UIAlertAction(title: "Gallery", style: UIAlertActionStyle.default, handler: { (alert:UIAlertAction!) -> Void in
self.photoLibrary()
}))
actionSheet.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil))
// if (UIDevice.current.userInterfaceIdiom == .pad) {
// let popover = actionSheet.popoverPresentationController
// popover?.sourceRect = self.view.bounds
// popover?.sourceView = self.pic1
// popover?.permittedArrowDirections = .any
// self.present(actionSheet, animated: true, completion: nil)
// } else {
self.present(actionSheet, animated: true, completion: nil)
//}
}
#IBAction func btnpic3Click(_ sender: Any) {
var profileStoryBoard: UIStoryboard!
profileStoryBoard = UIStoryboard(name:"\(Helper.manageStoryBoardName())ShowImage",bundle: nil)
let viewcontroller : ImageShowViewController = profileStoryBoard.instantiateViewController(withIdentifier: "ImageShowViewController") as! ImageShowViewController
viewcontroller.url = pic3path
self.present(viewcontroller, animated: false)
}
#IBAction func btnpic4Click(_ sender: Any) {
var profileStoryBoard: UIStoryboard!
profileStoryBoard = UIStoryboard(name:"\(Helper.manageStoryBoardName())ShowImage",bundle: nil)
let viewcontroller : ImageShowViewController = profileStoryBoard.instantiateViewController(withIdentifier: "ImageShowViewController") as! ImageShowViewController
viewcontroller.url = pic4path
self.present(viewcontroller, animated: false)
}
#IBAction func btnpic1Click(_ sender: UIButton) {
var profileStoryBoard: UIStoryboard!
profileStoryBoard = UIStoryboard(name:"\(Helper.manageStoryBoardName())ShowImage",bundle: nil)
let viewcontroller : ImageShowViewController = profileStoryBoard.instantiateViewController(withIdentifier: "ImageShowViewController") as! ImageShowViewController
viewcontroller.url = pic1path
self.present(viewcontroller, animated: false)
}
#IBAction func btnpic2Click(_ sender: UIButton) {
var profileStoryBoard: UIStoryboard!
profileStoryBoard = UIStoryboard(name:"\(Helper.manageStoryBoardName())ShowImage",bundle: nil)
let viewcontroller : ImageShowViewController = profileStoryBoard.instantiateViewController(withIdentifier: "ImageShowViewController") as! ImageShowViewController
viewcontroller.url = pic2path
self.present(viewcontroller, animated: false)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if picNumber == 1 {
pic1.image = info[UIImagePickerControllerOriginalImage] as? UIImage
uploadImage(image: (info[UIImagePickerControllerOriginalImage] as? UIImage)!)
} else if picNumber == 2 {
pic2.image = info[UIImagePickerControllerOriginalImage] as? UIImage
uploadImage(image: (info[UIImagePickerControllerOriginalImage] as? UIImage)!)
} else if picNumber == 3 {
pic3.image = info[UIImagePickerControllerOriginalImage] as? UIImage
uploadImage(image: (info[UIImagePickerControllerOriginalImage] as? UIImage)!)
} else {
pic4.image = info[UIImagePickerControllerOriginalImage] as? UIImage
uploadImage(image: (info[UIImagePickerControllerOriginalImage] as? UIImage)!)
}
self.dismiss(animated: true, completion: nil)
}
func uploadImage(image:UIImage) -> Void {
if Reachability.isConnectedToNetwork() == true {
self.showLoading(title: "uploding image");
let imgData = UIImageJPEGRepresentation(image, 0.2)!
var path :String = "";
let parameters = ["username": username]
Alamofire.upload(multipartFormData: { multipartFormData in
multipartFormData.append(imgData, withName: "images",fileName: "file.jpg", mimeType: "image/jpg")
for (key, value) in parameters {
multipartFormData.append((value?.data(using: String.Encoding.utf8)!)!, withName: key)
}
},
to:"http://www.dentalsa.net/api/api.php?method=radiaolog_image_update")
{ (result) in
switch result {
case .success(let upload, _, _):
upload.responseJSON { response in
self.hideLoading()
let value = response.result.value
let jsonResponse = JSON(value)
let status = jsonResponse["status"].stringValue
let message = jsonResponse["message"].stringValue
if status == "false" {
self.showAlerError(titleText: "Error", messagetext: message);
}
path = jsonResponse["path"].stringValue
if self.picNumber == 1 {
self.pic1path = path
} else if self.picNumber == 2 {
self.pic2path = path
} else if self.picNumber == 3 {
self.pic3path = path
} else if self.picNumber == 4 {
self.pic4path = path
}
print("ImagePath"+path)
}
case .failure(let encodingError):
print(encodingError)
}
}
} else {
self.showAlerError(titleText: "Error", messagetext: "Please check Internet connectivity");
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func makeComplainText(complain:String) -> String {
let characters = Array(complain.characters);
var data="";
if characters[0] == "1" {
data += "Check-Up, ";
}
if characters[1] == "1" {
data += "Teeth Cleaning, ";
}
if characters[2] == "1" {
data += "Periodontal Treatment, ";
}
if characters[3] == "1" {
data += "Dental Fillings, ";
}
if characters[4] == "1" {
data += "Prothesis, ";
}
if characters[5] == "1" {
data += "Extraction, ";
}
if characters[6] == "1" {
data += "Hollywoods smile, ";
}
if characters[7] == "1" {
data += "Children's Teeth, ";
}
if characters[8] == "1" {
data += "Bleaching, ";
}
return data;
}
#IBAction func saveClick(_ sender: UIButton) {
let netowrk = NetworkCall();
if Reachability.isConnectedToNetwork() == true {
self.showLoading(title: "Please wait")
netowrk.radiologyUpdate(username: username!,patientId: (patient?.patientID)!,picText1: pictext1.text!,picText2: pic2text.text!,picText3: pic3text.text!,picText4: pic4text.text!,pic1:pic1path,pic2:pic2path,pic3:pic3path,pic4:pic4path) { responseObject in
self.hideLoading()
if responseObject.status == "true" {
print("Success view controller");
self.showAlerError(titleText: "Success", messagetext: "Details saved Successfully");
} else {
self.showAlerError(titleText: "Error", messagetext: responseObject.message!);
}
return
}
} else {
self.showAlerError(titleText: "Error", messagetext: "Please check Internet connectivity");
}
}
func showLoading(title: String) {
strLabel.removeFromSuperview()
indicator.removeFromSuperview()
effectView.removeFromSuperview()
strLabel = UILabel(frame: CGRect(x: 50, y: 0, width: 160, height: 46))
strLabel.text = title
strLabel.font = UIFont.systemFont(ofSize: 14, weight: UIFontWeightMedium)
strLabel.textColor = UIColor(white: 0.9, alpha: 0.7)
effectView.frame = CGRect(x: view.frame.midX - strLabel.frame.width/2, y: view.frame.midY - strLabel.frame.height/2 , width: 160, height: 46)
effectView.layer.cornerRadius = 15
effectView.layer.masksToBounds = true
indicator = UIActivityIndicatorView(activityIndicatorStyle: .white)
indicator.frame = CGRect(x: 0, y: 0, width: 46, height: 46)
indicator.startAnimating()
effectView.addSubview(indicator)
effectView.addSubview(strLabel)
view.addSubview(effectView)
}
func setImage(imageview :UIImageView,url:String,indicator:UIActivityIndicatorView) -> Void {
Alamofire.request("http://www.dentalsa.net"+url).responseImage { response in
if let image = response.result.value {
indicator.isHidden = true
imageview.image = image
}
}
}
func hideLoading() {
self.effectView.removeFromSuperview()
//indicator.stopAnimating()
}
func showAlerError(titleText:String,messagetext:String) {
let alertController = UIAlertController(title: titleText, message:
messagetext, preferredStyle: UIAlertControllerStyle.alert)
alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.default,handler: nil))
self.present(alertController, animated: true, completion: nil)
}
#IBAction func backClick(_ sender: UIButton) {
_ = self.navigationController?.popViewController(animated: true)
}
func showFirstButton(show :Bool){
//conPic1height.constant = 150
btnShowPic1.isHidden = show
self.view.layoutIfNeeded()
}
func showSecondButton(show :Bool){
//conPic1height.constant = 150
btnShowPic2.isHidden = show
self.view.layoutIfNeeded()
}
func showThreeButton(show :Bool){
//conPic1height.constant = 150
btnShowPic3.isHidden = show
self.view.layoutIfNeeded()
}
func showFourButton(show :Bool){
//conPic1height.constant = 150
btnShowPic4.isHidden = show
self.view.layoutIfNeeded()
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
I need to capture image from camera and gallery on both iphone and iPad. I don't know what is the issue which i am facing here.

How to navigate to different storyboards along with sidemenu in swift 3

I am using third party control for sidemenu named : MMDrawerController, and m handling UI using multiple storyboards.let me come to the point my sidemenu looks like this : Sidemenu Image
Trying to achieve :
1)When I click on the Parent, "main.storyboard" should be displayed.
2)When I click on the Management, "management.storyboard" should be displayed.
same sidemenu should be displayed across all storyboard file.
I have tried some code by my own but m not getting the sidemenu on "management.storyboard" :(
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch(indexPath.row)
{
case 4:
let mainstoryboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var welview = mainstoryboard.instantiateViewController(withIdentifier: "WelcomeParentViewController") as! WelcomeParentViewController
var welnav = UINavigationController(rootViewController: welview)
var appdel : AppDelegate = UIApplication.shared.delegate as! AppDelegate
appdel.centerContainer!.centerViewController = welnav
appdel.centerContainer!.toggle(MMDrawerSide.left, animated: true, completion: nil)
break
case 5:
let mainstoryboard : UIStoryboard = UIStoryboard(name: "Management-Storyboard", bundle: nil)
var welview = mainstoryboard.instantiateViewController(withIdentifier: "ReportsViewController") as! ReportsViewController
var welnav = UINavigationController(rootViewController: welview)
var appdel : AppDelegate = UIApplication.shared.delegate as! AppDelegate
appdel.centerContainer!.centerViewController = welnav
appdel.centerContainer!.toggle(MMDrawerSide.left, animated: true, completion: nil)
break
default :
break
}
I want same sidemenu across all storyboard file.
how to accomplish the above feature.Please Help.Thank you in advance.
MMDrawerController Code inside the appdelegate.swift
import UIKit
import GoogleMaps
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var centerContainer : MMDrawerController?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
if isUserLoggedIn()
{
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.gotoMainvc()
}
else
{
let rootViewController = self.window!.rootViewController
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let setViewController = mainStoryboard.instantiateViewController(withIdentifier: "LoginViewController") as! LoginViewController
rootViewController?.navigationController?.popToViewController(setViewController, animated: false)
}
return true
}
func isUserLoggedIn() -> Bool{
if let accessToken = UserDefaults.standard.object(forKey: "access_token") as? String
{
if (accessToken.characters.count) > 0{
return true
} else {
return false
}
}
else {
return false
}
}
func gotoMainvc()
{
var rootviewcontroller = self.window?.rootViewController
if(UIDevice.current.userInterfaceIdiom == .phone)
{
let mainstoryboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var centerviewcontroller = mainstoryboard.instantiateViewController(withIdentifier: "WelcomeParentViewController") as! WelcomeParentViewController
var leftsideviewcontroller = mainstoryboard.instantiateViewController(withIdentifier: "LeftSideMenuViewController") as! LeftSideMenuViewController
let leftsidenav = UINavigationController(rootViewController: leftsideviewcontroller)
let centernav = UINavigationController(rootViewController: centerviewcontroller)
centerContainer = MMDrawerController(center: centernav, leftDrawerViewController: leftsidenav)
centerContainer?.openDrawerGestureModeMask = MMOpenDrawerGestureMode.panningCenterView
centerContainer?.closeDrawerGestureModeMask = MMCloseDrawerGestureMode.panningCenterView
window?.rootViewController = centerContainer
window?.makeKeyAndVisible()
}
else{
let mainstoryboard2 : UIStoryboard = UIStoryboard(name: "Storyboard-iPad", bundle: nil)
var centerviewcontroller = mainstoryboard2.instantiateViewController(withIdentifier: "WelcomeParentViewController") as! WelcomeParentViewController
var leftsideviewcontroller = mainstoryboard2.instantiateViewController(withIdentifier: "LeftSideMenuViewController") as! LeftSideMenuViewController
let leftsidenav = UINavigationController(rootViewController: leftsideviewcontroller)
let centernav = UINavigationController(rootViewController: centerviewcontroller)
centerContainer = MMDrawerController(center: centernav, leftDrawerViewController: leftsidenav)
centerContainer?.openDrawerGestureModeMask = MMOpenDrawerGestureMode.panningCenterView
centerContainer?.closeDrawerGestureModeMask = MMCloseDrawerGestureMode.panningCenterView
window?.rootViewController = centerContainer
window?.makeKeyAndVisible()
}
}
//MARK: sharedDelegate
func sharedDelegate() -> AppDelegate
{
return UIApplication.shared.delegate as! AppDelegate
}
}
Main View Controller
import UIKit
class ViewController: UIViewController , UICollectionViewDelegate , UICollectionViewDataSource , UIGestureRecognizerDelegate {
#IBOutlet weak var collectioncell: UICollectionView!
var objectProfile:SideMenuViewController!
var tapGesture = UITapGestureRecognizer()
override func viewDidLoad() {
super.viewDidLoad()
tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.myviewTapped(_:)))
tapGesture.numberOfTapsRequired = 1
tapGesture.numberOfTouchesRequired = 1
collectioncell.addGestureRecognizer(tapGesture)
collectioncell.isUserInteractionEnabled = true
let storyboard = UIStoryboard(name: "Main", bundle: nil)
self.objectProfile = storyboard.instantiateViewController(withIdentifier: "SideMenuViewController") as! SideMenuViewController
self.objectProfile.view.frame = CGRect(x: -(self.view.frame.size.width - 40), y: 0, width: self.view.frame.size.width - 40, height: self.view.frame.size.height)
self.view.addSubview(self.objectProfile.view)
self.navigationController?.didMove(toParentViewController: self.objectProfile)
self.collectioncell.layer.cornerRadius = 5.0
self.collectioncell.layer.borderWidth = 5.0
self.collectioncell.clipsToBounds = true
self.collectioncell.layer.borderColor = UIColor.clear.cgColor
self.collectioncell.layer.masksToBounds = true
}
func myviewTapped(_ sender: UITapGestureRecognizer) {
if self.objectProfile.view.isHidden == false {
UIView.animate(withDuration: 0.3)
{
self.objectProfile.view.frame = CGRect(x: -(self.view.frame.size.width - 90), y: 0, width: self.view.frame.size.width - 90, height: self.view.frame.size.height)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func Mrnupressed(_ sender: UIBarButtonItem) {
UIView.animate(withDuration: 0.3)
{
self.objectProfile.view.frame = CGRect(x: 0 , y: 0, width: (self.view.frame.size.width - 100), height: self.view.frame.size.height)
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return 6
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCell", for: indexPath) as! MainCollectionViewCell
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize {
let cellsize = CGSize(width: (collectioncell.bounds.size.width/2) - 12, height:(collectioncell.bounds.size.height/3) - 20)
return cellsize
}
}
Child View Controller
import UIKit
class SideMenuViewController: UIViewController,UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var sidemenutable: UITableView!
var stri:String!
var ArrarMenu:[String] = ["Home","SiteMep","Student","About Us","Help"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return ArrarMenu.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SideMenuCell") as! SideMenuTableViewCell
let objarray = ArrarMenu[indexPath.row]
cell.lblitem.text = objarray
stri = objarray
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0{
self.performSegue(withIdentifier: "SegueForHome", sender: self)
}
}
}
In This Code I Am use Child View As Side Manu Controller
here is code open side from other storyboard
#IBAction func menutapped(_ sender: Any) {
var appdelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
appdelegate.centerContainer?.toggle(MMDrawerSide.left, animated: true, completion: nil)
}

Can not cast value of type to 'UIPageViewController'

So I am new to iOS development. I am trying to make a page swipe functionality like an image carousel or like an app tutorial, and I'm Running into a Thread 1: signal SIGABRT error. in the log is states 'Can not cast value of type 'ViewController' to 'UIPageViewController'
not sure you need the entire code.
my problem line is:
self.pageViewController = self.storyboard?.instantiateViewController(withIdentifier: "contentViewController") as! UIPageViewController
help will be greatly appreciated.
class ViewController: UIViewController, UIPageViewControllerDataSource {
var pageViewController: UIPageViewController!
var pageTitles: NSArray!
var pageImages: NSArray!
override func viewDidLoad() {
self.pageTitles = NSArray(objects: " By Request","Subscription Plan","Flex Plan","Everyday Plan", "Welocme")
self.pageImages = NSArray(objects: "page1","page2","page3","page4","page5")
self.pageViewController = self.storyboard?.instantiateViewController(withIdentifier: "contentViewController") as! UIPageViewController
self.pageViewController.dataSource = self
let startVC = self.viewControllerAtIndex(index: 0) as ContentViewController
let viewControllers = NSArray(object: startVC)
self.pageViewController.setViewControllers(viewControllers as? [UIViewController], direction: .forward, animated: true, completion: nil)
self.pageViewController.view.frame = CGRect(x: 0, y:0, width: Int(self.view.frame.width), height: Int(self.view.frame.size.height - 60))
self.addChildViewController(self.pageViewController)
self.view.addSubview(self.pageViewController.view)
self.pageViewController.didMove(toParentViewController: self)
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func loginAction(_ sender: AnyObject) {
}
#IBAction func signupAction(_ sender: AnyObject) {
}
func viewControllerAtIndex(index: Int) -> ContentViewController {
if ((self.pageTitles.count == 0) || (index >= self.pageTitles.count)) {
return ContentViewController()
}
var vc: ContentViewController = self.storyboard?.instantiateViewController(withIdentifier: "pageViewController") as! ContentViewController
vc.imageFile = self.pageImages[index] as! String
vc.titleText = self.pageTitles[index] as! String
vc.pageIndex = index
return vc
}
// MARK: - Page Vuew Controller Data Source
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let vc = viewController as! ContentViewController
var index = vc.pageIndex as Int
if ((index == 0) || (index == NSNotFound)) {
return nil
}
index -= 1
return self.viewControllerAtIndex(index: index)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
var vc = viewController as! ContentViewController
var index = vc.pageIndex as Int
if (index == NSNotFound) {
return nil
}
index += 1
if (index == self.pageTitles.count) {
return nil
}
return self.viewControllerAtIndex(index: index)
}
func presentationCount(for pageViewController: UIPageViewController) -> Int {
return self.pageTitles.count
}
func presentationIndex(for pageViewController: UIPageViewController) -> Int {
return 0
}
}

Error in conversion Swift 2 to Swift 3 MKDirections and MKDirections

I am having difficulties converting two sections of code from Swift 2 to Swift 3
The working Swift 2 Code Block was
func showRoute(routes: [MKRoute], time: NSTimeInterval) {
var directionsArray = [(startingAddress: String, endingAddress: String, route: MKRoute)]()
for i in 0..<routes.count {
plotPolyline(routes[i])
directionsArray += [(locationArray[i].textField.text!,
locationArray[i+1].textField.text!, routes[i])]
}
displayDirections(directionsArray)
printTimeToLabel(time)
}
Swift 3 has converted this to
func showRoute(routes: [MKRoute], time: TimeInterval) {
var directionsArray = [(startingAddress: String, endingAddress: String, route: MKRoute)]()
for i in 0..<routes.count {
plotPolyline(route: routes[i])
directionsArray += [(locationArray[i].textField?.text,
locationArray[i+1].textField?.text, routes[i])]
}
displayDirections(directionsArray: directionsArray)
printTimeToLabel(time: time)
}
This produces an error on the line
directionsArray += [(locationArray[i].textField?.text,
locationArray[i+1].textField?.text, routes[i])]
Cannot convert value of type '[(startingAddress: String, endingAddress: String, route: MKRoute)]' to expected argument type 'inout _'
If anyone can help i would really appreciate it
Just need
directionsArray += [(startingAddress : locationArray[i].textField!.text!,
endingAddress : locationArray[i+1].textField!.text!,
route : routes[i])]
I saw your question, but There are no answers. And, That is not only one problem.
Here is full body of ViewController:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController {
#IBOutlet weak var sourceField: UITextField!
#IBOutlet weak var destinationField1: UITextField!
#IBOutlet weak var destinationField2: UITextField!
#IBOutlet weak var topMarginConstraint: NSLayoutConstraint!
#IBOutlet var enterButtonArray: [UIButton]!
var originalTopMargin: CGFloat!
let locationManager = CLLocationManager()
var locationTuples: [(textField: UITextField?, mapItem: MKMapItem?)]!
var locationsArray: [(textField: UITextField?, mapItem: MKMapItem?)] {
var filtered = locationTuples.filter({ $0.mapItem != nil })
filtered += [filtered.first!]
return filtered
}
override func viewDidLoad() {
super.viewDidLoad()
originalTopMargin = topMarginConstraint.constant
locationTuples = [(sourceField, nil), (destinationField1, nil), (destinationField2, nil)]
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.requestLocation()
}
}
override func viewWillAppear(_ animated: Bool) {
navigationController?.isNavigationBarHidden = true
}
#IBAction func getDirections(_ sender: AnyObject) {
view.endEditing(true)
performSegue(withIdentifier: "show_directions", sender: self)
}
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
if locationTuples[0].mapItem == nil ||
(locationTuples[1].mapItem == nil && locationTuples[2].mapItem == nil) {
showAlert("Please enter a valid starting point and at least one destination.")
return false
} else {
return true
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let directionsViewController = segue.destination as! DirectionsViewController
directionsViewController.locationArray = locationsArray
}
#IBAction func addressEntered(_ sender: UIButton) {
view.endEditing(true)
let currentTextField = locationTuples[sender.tag-1].textField
CLGeocoder().geocodeAddressString(currentTextField!.text!,
completionHandler: {(placemarks, error) -> Void in
if let placemarks = placemarks {
var addresses = [String]()
for placemark in placemarks {
addresses.append(self.formatAddressFromPlacemark(placemark))
}
self.showAddressTable(addresses, textField:currentTextField!,
placemarks:placemarks, sender:sender)
} else {
self.showAlert("Address not found.")
}
} )
}
func showAddressTable(_ addresses: [String], textField: UITextField,
placemarks: [CLPlacemark], sender: UIButton) {
let addressTableView = AddressTableView(frame: UIScreen.main.bounds, style: UITableViewStyle.plain)
addressTableView.addresses = addresses
addressTableView.currentTextField = textField
addressTableView.placemarkArray = placemarks
addressTableView.mainViewController = self
addressTableView.sender = sender
addressTableView.delegate = addressTableView
addressTableView.dataSource = addressTableView
view.addSubview(addressTableView)
}
func formatAddressFromPlacemark(_ placemark: CLPlacemark) -> String {
return (placemark.addressDictionary!["FormattedAddressLines"] as! [String]).joined(separator: ", ")
}
#IBAction func swapFields(_ sender: AnyObject) {
swap(&destinationField1.text, &destinationField2.text)
swap(&locationTuples[1].mapItem, &locationTuples[2].mapItem)
swap(&self.enterButtonArray.filter{$0.tag == 2}.first!.isSelected, &self.enterButtonArray.filter{$0.tag == 3}.first!.isSelected)
}
func showAlert(_ alertString: String) {
let alert = UIAlertController(title: nil, message: alertString, preferredStyle: .alert)
let okButton = UIAlertAction(title: "OK",
style: .cancel) { (alert) -> Void in
}
alert.addAction(okButton)
present(alert, animated: true, completion: nil)
}
// The remaining methods handle the keyboard resignation/
// move the view so that the first responders aren't hidden
func moveViewUp() {
if topMarginConstraint.constant != originalTopMargin {
return
}
topMarginConstraint.constant -= 165
UIView.animate(withDuration: 0.3, animations: { () -> Void in
self.view.layoutIfNeeded()
})
}
func moveViewDown() {
if topMarginConstraint.constant == originalTopMargin {
return
}
topMarginConstraint.constant = originalTopMargin
UIView.animate(withDuration: 0.3, animations: { () -> Void in
self.view.layoutIfNeeded()
})
}
}
extension ViewController: UITextFieldDelegate {
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
enterButtonArray.filter{$0.tag == textField.tag}.first!.isSelected = false
locationTuples[textField.tag-1].mapItem = nil
return true
}
func textFieldDidBeginEditing(_ textField: UITextField) {
moveViewUp()
}
func textFieldDidEndEditing(_ textField: UITextField) {
moveViewDown()
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
view.endEditing(true)
moveViewDown()
return true
}
}
extension ViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
CLGeocoder().reverseGeocodeLocation(locations.last!,
completionHandler: {(placemarks, error) -> Void in
if let placemarks = placemarks {
let placemark = placemarks[0]
self.locationTuples[0].mapItem = MKMapItem(placemark:
MKPlacemark(coordinate: placemark.location!.coordinate,
addressDictionary: placemark.addressDictionary as! [String:AnyObject]?))
self.sourceField.text = self.formatAddressFromPlacemark(placemark)
self.enterButtonArray.filter{$0.tag == 1}.first!.isSelected = true
}
})
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
}
}