This question already has answers here:
Programmatically Added Constraint Not Working
(2 answers)
Closed 2 years ago.
I am trying to set up the map view programmatically and i have set up the constraints down below but when i run the simulator it is just showing a blank screen. I want to pin the map view to the top,bottom,left,right in the view.
class ViewController: UIViewController {
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.view.backgroundColor = .white
configureScreen()
}
let map: MKMapView = {
let map = MKMapView()
map.backgroundColor = .black
return map
}()
func configureScreen(){
view.addSubview(map)
NSLayoutConstraint.activate([
map.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor,constant: 100),
map.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor,constant: 0),
map.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor,constant: 0),
map.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor,constant: 0)
])
}
}
Because you forgot to say
map.translatesAutoresizingMaskIntoConstraints = false
Related
This question already has answers here:
How to set image in circle in swift
(16 answers)
Closed 2 years ago.
I have used the following method to make the image rounded, but the results are not the desired ones. I have shared my code and the result in the description below. Any suggestions would be highly appreciated. Thanks!
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var image1: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.async(execute:{self.image1.setRounded()})
// Do any additional setup after loading the view.
}
extension UIImageView {
func setRounded() {
let radius = self.frame.width / 2
self.layer.cornerRadius = radius
self.layer.masksToBounds = true
}
}
Results :-
To make the image rounded, you have to make the height equal to the width. And then try:
extension UIImageView {
func setRounded() {
layer.cornerRadius = bounds.height/2
layer.masksToBounds = true
}
}
And call it inside viewDidLayoutSubviews.
override func viewDidLayouSubviews() {
super.viewDidLayouSubviews()
image1.setRounded()
}
I'm trying to add a search bar to a navigation map for MapBox on iOS, but having some trouble. I'm trying to do it programmatically in this case, as I don't have a great handle on storyboard. I've tried messing around with the zIndex as well, but still no search bar shows up for me.
Here's the code I've got so far:
class ViewController: UIViewController, UISearchBarDelegate, MGLMapViewDelegate {
var mapView: NavigationMapView!
lazy var directions: DirectionsManager = DirectionsManager()
var searchBar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
// Setup mapbox
let styleURL = URL(string: "style")
mapView = NavigationMapView(frame: view.bounds, styleURL: styleURL)
view.addSubview(mapView)
mapView.delegate = self
mapView.showsUserLocation = true
mapView.setUserTrackingMode(.follow, animated: true)
mapView.localizeLabels()
self.searchBar = UISearchBar()
mapView.addSubview(searchBar)
}
#erikpartridge, It's not an issue with mapbox, you need to set frame for UISearchBar like the below,
self.searchBar = UISearchBar(frame: CGRect(x: 15, y: 50, width: (view.bounds.width-30), height: 50))
mapView.addSubview(searchBar)
The code below has a uicolor box when pressed, the box becomes a smaller uicolor box. The problem is that the color box can only be pressed one time. So the box can go from large to small but it cant go from small to big. How can the code be written so when the box is clicked the box goes from big to small or small to big every time.
import UIKit
class ViewController: UIViewController {
let colorview = UIView()
var initialc = [NSLayoutConstraint]()
override func viewDidLoad() {
super.viewDidLoad()
let tapGestureRecognizer = UITapGestureRecognizer(target:self, action:#selector(ViewController.myFunction(_:)))
colorview.userInteractionEnabled = true
colorview.addGestureRecognizer(tapGestureRecognizer)
colorview.translatesAutoresizingMaskIntoConstraints = false
colorview.backgroundColor = UIColor.blueColor()
self.view.addSubview((colorview))
let leadingc = colorview.leadingAnchor.constraintEqualToAnchor(self.view.leadingAnchor)
let trailingC = colorview.trailingAnchor.constraintEqualToAnchor(self.view.trailingAnchor)
let topc = colorview.topAnchor.constraintEqualToAnchor(self.view.topAnchor)
let bottomc = colorview.bottomAnchor.constraintEqualToAnchor(self.view.bottomAnchor, constant: -50)
initialc.appendContentsOf([leadingc,trailingC,topc,bottomc])
NSLayoutConstraint.activateConstraints(initialc)
}
func myFunction(sender: AnyObject) {
NSLayoutConstraint.deactivateConstraints(initialc)
let widthc = colorview.widthAnchor.constraintEqualToConstant(100)
let heightc = colorview.heightAnchor.constraintEqualToConstant(100)
let centerxc = colorview.centerXAnchor.constraintEqualToAnchor(self.view.centerXAnchor)
let centeryc = colorview.centerYAnchor.constraintEqualToAnchor(self.view.centerYAnchor)
NSLayoutConstraint.activateConstraints([widthc,heightc,centerxc,centeryc])
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You are resizing the view in an awkward way. Instead of using constraints, don't place them. Tell the view where to go with its frame. If you need the view to animate the change between frames then use UIView.animateViewWithDuration() and inside the function do the frame changes you desire. This keeps transitions smooth and full control in your hands. Constraints are not as easy to implement properly during run time as frames.
I have found this answer How to check text field input at real time?
This is what I am looking for. However I am having trouble actually implementing this code. Also my current geographical location makes googling almost impossible.
I want to be able to change the background color of the next text field if the correct number is entered into the previous text field. textfieldTwo background color will change to green if the correct value is entered in textFieldOne. If the value is incorrect then nothing will happen. Please help me out. I have two text fields called textFieldOne and textFieldTwo and nothing else in the code.
Just pop this in your main view controller in an empty project (try using iphone 6 on the simulator)
import UIKit
class ViewController: UIViewController {
var txtField:UITextField!
var txtFieldTwo:UITextField!
var rightNumber = 10
override func viewDidLoad() {
super.viewDidLoad()
//txtFieldOne
var txtField = UITextField()
txtField.frame = CGRectMake(100, 100, 200, 40)
txtField.borderStyle = UITextBorderStyle.None
txtField.backgroundColor = UIColor.blueColor()
txtField.layer.cornerRadius = 5
self.view.addSubview(txtField)
//txtFieldTwo
var txtFieldTwo = UITextField()
txtFieldTwo.frame = CGRectMake(100, 150, 200, 40)
txtFieldTwo.borderStyle = UITextBorderStyle.None
txtFieldTwo.backgroundColor = UIColor.blueColor()
txtFieldTwo.layer.cornerRadius = 5
self.view.addSubview(txtFieldTwo)
txtField.addTarget(self, action: "checkForRightNumber", forControlEvents: UIControlEvents.AllEditingEvents)
self.txtField = txtField
self.txtFieldTwo = txtFieldTwo
}
func checkForRightNumber() {
let number:Int? = self.txtField.text.toInt()
if number == rightNumber {
self.txtFieldTwo.backgroundColor = UIColor.greenColor()
} else {
self.txtFieldTwo.backgroundColor = UIColor.blueColor()
}
}
}
EDIT: Adding a version with IBOutlets and IBActions
Note that in this example the IBAction is connected to txtFieldOne on Sent Events / Editing Changed
Also, make sure your Text Fields border colors are set to None. In the storyboard, the way to do this is to choose the left most option with the dashed border around it. That's so you can color the backgrounds. You can use layer.cornerRadius to set the roundness of the border's edges.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var txtField: UITextField!
#IBOutlet weak var txtFieldTwo: UITextField!
var rightNumber = 10
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func checkForRightNumber(sender: AnyObject) {
let number:Int? = self.txtField.text.toInt()
if number == rightNumber {
self.txtFieldTwo.backgroundColor = UIColor.greenColor()
} else {
self.txtFieldTwo.backgroundColor = UIColor.blueColor()
}
}
}
I have 2 annotations to display on the mapview, but unable to set the maprect to show all of them on screen without requiring users to zoom out.
I tried with showAnnotations but no luck. Anyone has been able to do this in Swift and Xcode 6.1.1?
Here is my code:
class ViewController: UIViewController, MKMapViewDelegate {
#IBOutlet var map: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
var mapView = map
// 1
let point1 = CLLocationCoordinate2D(latitude: 38.915565, longitude: -77.093524)
let point2 = CLLocationCoordinate2D(latitude: 38.890693, longitude: -76.933318)
//2
let annotation = MKPointAnnotation()
annotation.setCoordinate(point1)
annotation.title = "point1"
map.addAnnotation(annotation)
let annotation2 = MKPointAnnotation()
annotation2.setCoordinate(point2)
annotation2.title = "point2"
map.addAnnotation(annotation2)
//3
// option1: set maprect to cover all annotations, doesn't work
var points = [annotation, annotation2]
var rect = MKMapRectNull
for p in points {
let k = MKMapPointForCoordinate(p.coordinate)
rect = MKMapRectUnion(rect, MKMapRectMake(k.x, k.y, 0.1, 0.1))
println("result: x = \(rect.origin.x) y = \(rect.origin.y)")
}
map.setVisibleMapRect(rect, animated: true)
// option 2: using showAnnotations, doesn't work
//map.showAnnotations(points, animated: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
This is what I got currently:
This is what I expected to see:
Thanks for your help.
I finally found out why the pins of the annotations had not been displayed in the visible region of the screen. I think the MapKit framework behaves a bit different than in the previous versions. Since I use autolayout to allow the map to expand to the entire screen for all devices (iPhones, iPad), setVisibleMapRect or mapView.showAnnotations of the map should be invoked in mapViewDidFinishLoadingMap, not in viewDidLoad of the view controller
For example:
func mapViewDidFinishLoadingMap(_ mapView: MKMapView) {
// this is where visible maprect should be set
mapView.showAnnotations(mapView.annotations, animated: true)
}
I had this same problem when I called
viewDidLoad() {
mapView.showAnnotations(myAnnotations, animated: false)
}
However, moving the call to viewDidLayoutSubviews() also seems to fix the problem (not that isInitialLoad is initialized to true in viewDidLoad).
viewDidLayoutSubviews() {
if isInitialLoad {
mapView.showAnnotations(myAnnotations, animated: false)
isInitialLoad = false
}
}
The difference (I think it is an advantage) of putting the call in viewDidLayoutSubviews is that the map hasn't actually displayed yet, so your initial display is that area defined by the annotations. However, it seems that it is called every time the map zooms, so you need to be sure to only call it the first time.
For me using showing annotations after map did finish loading did not work.
func mapViewDidFinishLoadingMap(mapView: MKMapView!) {
// this is where visible maprect should be set
mapView.showAnnotations(mapView.annotations, animated: true)
}
Besides showing the annotation, I needed to calculate polylines to connect the annotations and map finished loading was triggered too early.
Instead I tried mapViewDidFinishRenderingMap and it worked perfectly fine. See example below:
//MARK: - Show all objects after adding them on the map
func mapViewDidFinishRenderingMap(mapView: MKMapView, fullyRendered: Bool) {
mapView.showAnnotations(mapStages, animated: true)
}
You can try this.
I created an extension to show all the annotations using some code from here and there in swift 2.3. This will not show all annotations if they can't be shown even at maximum zoom level.
import MapKit
extension MKMapView {
func fitAllAnnotations() {
var zoomRect = MKMapRectNull;
for annotation in annotations {
let annotationPoint = MKMapPointForCoordinate(annotation.coordinate)
let pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
zoomRect = MKMapRectUnion(zoomRect, pointRect);
}
setVisibleMapRect(zoomRect, edgePadding: UIEdgeInsetsMake(20, 20, 20, 20), animated: true)
}
}