View stuck behind MapView - ios

I have tried everything to make my view appear over the map view (see code below), but it still won't show up. I don't know what to do. This is the mapView at 0.5 alpha
segmentedControl = DPSegmentedControl.init(
FrameWithoutIcon: CGRectMake(307.5, 566, 235, 37.5),
items: ["Standard", "Satellite", "Hybrid"],
backgroundColor: UIColor(red: 230/255, green: 230/255, blue: 230/255, alpha: 1),
thumbColor: UIColor.init(hex: "#B60002"),
textColor: UIColor(hex: "#808080"),
selectedTextColor: UIColor(hex: "#FFFFFF"))
segmentedControl.alpha = 0
segmentedControl.selectedIndex = 0
segmentedControl.addTarget(self, action: #selector(self.tapSegment(_:)), forControlEvents: .ValueChanged)
self.view.insertSubview(self.segmentedControl, belowSubview: self.hoverBar)
UIApplication.sharedApplication().keyWindow!.bringSubviewToFront(self.segmentedControl)
UIApplication.sharedApplication().keyWindow!.sendSubviewToBack(self.mapView)
When I use z position, the view appears, but it does not allow any touch actions (it is a custom segmented control).
self.segmentedControl.layer.zPosition = self.mapView.layer.zPosition + 1

Have your tried either of these?
self.view.bringSubviewToFront(self.segmentedControl)
self.view.sendSubviewToBack(self.mapView)
or
self.segmentedControl?.superview.bringSubviewToFront(self.segmentedControl)
self.mapView?.superview.sendSubviewToBack(self.mapView)

Related

Gradually change color to PIN (Mark Location) on the map

I have a screen of my app that uses the iOS UIMap Map. On the map there are PINs (Mark Location of Apple's Human Interface) that indicate seismometers, and every 6 seconds the map updates and some of these seismometers vibrate and turn red. I have to give the PINs on the map a fade effect, going from bright red to very light red.
if annotation.identifier == "redpin" {
view.pinTintColor = .red
DispatchQueue.main.asyncAfter(deadline: .now()+2.0 ) {
view.pinTintColor = UIColor(red: 255/255, green: 110/255, blue: 110/255, alpha: 1)
}
DispatchQueue.main.asyncAfter(deadline: .now()+2.0 ) {
view.pinTintColor = UIColor(red: 255/255, green: 180/255, blue: 180/255, alpha: 1)
}
DispatchQueue.main.asyncAfter(deadline: .now()+2.0 ) {
view.pinTintColor = UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 1)
}
}
I used this method, using a timer that changes the color of the PINs that vibrate every 2 seconds, giving this fade effect manually. For the first ones that vibrate on the first update this is fine, but then those that come after keep the last color (white) and not red-red light-white.
Can anyone help me?
A call to DispatchQueue.main.asyncAfter(deadline: .now()+2.0) block does not wait until it's done... the next line of code will be executed immediately.
So, in your posted code, you are effectively saying:
set the pin to Red
wait 2 seconds
set the pin to Medium Red
set the pin to Light Red
set the pin to White
You could fix this with using:
.now()+0.25 // wait 1/4 second
.now()+0.50 // wait 1/2 second
.now()+0.75 // wait 3/4 second
so each block would execute 1/4 second after the previous one.
Tint Color cannot be animated, so you cannot use it in a UIView.animate() block.
However, red-white-red Pin tint color changes do look a little "fadey" so you might be happy with:
func animPinColor(_ v: MKPinAnnotationView) -> Void {
// set pin to white
v.pinTintColor = .white
// wait 0.25 seconds ... adjust as desired
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
// set pin back to red
v.pinTintColor = .red
}
}
Or, if you want a little more control:
func animPinColor(_ v: MKPinAnnotationView) -> Void {
// verbose, for clarity
let red = UIColor(red: 255/255, green: 0, blue: 0, alpha: 1)
let mediumRed = UIColor(red: 255/255, green: 110/255, blue: 110/255, alpha: 1)
let lightRed = UIColor(red: 255/255, green: 180/255, blue: 180/255, alpha: 1)
let white = UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 1)
let colors: [UIColor] = [
mediumRed,
lightRed,
white,
lightRed,
mediumRed,
red,
]
// 1/2 second color animation ... adjust as desired
let totalDuration: Double = 0.5
// each step will take totalDuration divided by total steps
let relativeDuration = totalDuration / Double(colors.count)
for i in 0..<colors.count {
DispatchQueue.main.asyncAfter(deadline: .now() + Double(i) * relativeDuration) {
v.pinTintColor = colors[i]
}
}
}
You can play with the duration / timing, and could even add more "shades of red" to get an even smoother fade.
Edit
Based on the code you posted, I'm assuming you have a reference to a MKPinAnnotationView?
If so, usage would be:
if annotation.identifier == "redpin" {
//view.pinTintColor = .red
animPinColor(view)
}

How to hide elements in a Stack View

I have 4 separate views and I want to hide the other 3 of them when one of the buttons is pressed.
I have them in a UIStackView but .isHidden = true does not hide the views for some reason.
It works fine when they're not in a stack view.
#IBAction func qbpressed(_ sender: Any) {
QBContainer.isHidden = false
WRContainer.isHidden = true
RBContainer.isHidden = true
QBIndicator.isHidden = false
WRIndicator.isHidden = true
RBIndicator.isHidden = true
TEIndicator.isHidden = true
QBButton.setTitleColor(#colorLiteral(red: 0, green: 0.5008062124, blue: 1, alpha: 1), for: .normal)
WRButton.setTitleColor(#colorLiteral(red: 0.7540688515, green: 0.7540867925, blue: 0.7540771365, alpha: 1), for: .normal)
RBButton.setTitleColor(#colorLiteral(red: 0.7540688515, green: 0.7540867925, blue: 0.7540771365, alpha: 1), for: .normal)
TEButton.setTitleColor(#colorLiteral(red: 0.7540688515, green: 0.7540867925, blue: 0.7540771365, alpha: 1), for: .normal)
if intersitial.isReady{
intersitial.present(fromRootViewController: self)
}
}
isHidden property doesn't work, but you can use alpha and achieve the same result,
QBIndicator.alpha = 1.0 will work for QBIndicator.isHidden = false and
QBIndicator.alpha = 0.0 will work for QBIndicator.isHidden = true
setting a view to hidden should make it no longer visible, regardless of whether or not it inside a UIStackView.
The benefit of UIStackView is that it provides free animation through the isHidden property, like so:
// Assuming stackViewSubView.isHidden == false here
UIView.animate(withDuration: 0.25, animations: {
self.stackViewSubView.isHidden = true
self.view.layoutIfNeeded()
})

UIButton not working loaded in a child ViewController

I've got a MainViewController where I'm loading a slideout-menu. The MainViewController contains a static TopView and a ContentView where different child controllers or views are loaded, depending on which menu entry was selected.
There is a button inside one of the children is loaded, but it is not working.
When I start the app with the ViewController including the button, set to "is initial View Controller", everything works properly.
When starting the app with the MainViewController as initial View Controller with a loaded child, the button is not working (it is loaded in the view, but not reacting).
Any suggestions how I can make this work?
MainViewController loading of Child View
class MainViewController: UIViewController, SideBarDelegate {
var contentView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
....
contentView.backgroundColor = UIColor(red: 70/255, green: 174/255, blue: 253/255, alpha: 1)
contentView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(contentView)
contentView.topAnchor.constraint(equalTo: statusBarView.bottomAnchor).isActive = true
contentView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
contentView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
contentView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
contentView.layoutIfNeeded()
}
func sideBarDidSelectButtonAtIndex(_ index: Int) {
...
if index == 0{
statusBarLabel.text = "First"
let controller:FirstViewController = storyboard!.instantiateViewController(withIdentifier: "First") as! FirstViewController
controller.view.frame = ContentView.bounds
controller.willMove(toParentViewController: self)
contentView.addSubview(controller.view)
controller.didMove(toParentViewController: self)
print("touched index 0")
} else if index == 1{
// index is 1
}
}
FirstViewController
class FirstViewController: UIViewController, UIScrollViewDelegate {
let addButton = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(red: 230/255, green: 230/255, blue: 230/255, alpha: 1)
addButton.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 60)
addButton.clipsToBounds = true
addButton.setTitleColor(UIColor.white, for: .normal)
addButton.backgroundColor = UIColor(red: 102/255, green: 204/255, blue: 255/255, alpha: 1)
addButton.setTitle("add feed", for: .normal)
addButton.titleLabel?.font = UIFont.systemFont(ofSize: 20, weight: UIFontWeightRegular)
self.view.addSubview(AddButton)
addButton.layoutIfNeeded()
addButton.addTarget(self, action: #selector(touchUpAddButton), for: UIControlEvents.touchUpInside)
addButton.addTarget(self, action: #selector(touchDownAddButton), for: UIControlEvents.touchDown)
func touchUpAddButton() {
addButton.backgroundColor = UIColor(red: 102/255, green: 204/255, blue: 255/255, alpha: 1)
}
func touchDownAddButton() {
addButton.backgroundColor = UIColor(red: 70/255, green: 174/255, blue: 253/255, alpha: 1)
}
}
While adding the view in the container you don't have to use addSubview function, that the FirstViewController functionality is not working.
Use below code:
let newViewController:FirstViewController = storyboard!.instantiateViewController(withIdentifier: "First") as! FirstViewController
let oldViewController = childViewControllers.last! as UIViewController
oldViewController.willMove(toParentViewController: nil)
addChildViewController(newViewController)
transition(from: oldViewController, to: newViewController, duration: 0.25, options: .transitionCrossDissolve, animations:{ () -> Void in
// nothing needed here
}, completion: { (finished) -> Void in
oldViewController.removeFromParentViewController()
newViewController.didMove(toParentViewController: self)
})
You can change the duration, it used for animation
Update your functions to these
func TouchUpAddButton(sender: UIButton){
addButton.backgroundColor = UIColor(red: 102/255, green: 204/255, blue: 255/255, alpha: 1)
}
func TouchDownAddButton(sender: UIButton) {
addButton.backgroundColor = UIColor(red: 70/255, green: 174/255, blue: 253/255, alpha: 1)
}
And change your code of adding the target to
addButton.addTarget(self, action: #selector(FirstViewController.touchUpAddButton(_:)), for: .touchDown)
addButton.addTarget(self, action: #selector(FirstViewController.touchDownAddButton(_:)), for: .touchDown)
First solution:
Remove an autolayout constrains
Second solution:
Button is not performing an action because a child view controller view should be added directly to a container controller view (in your case: MainViewController view) and not via an intermediate view (in your case: contentView)

Programmatically changing button shadows is working for all but the first row, yet the first row's background is indeed changing?

I have 4 stackViews, each containing a set of buttons for a custom keyboard. I have a function that edits their appearance. I have added a shadow offset:
btn.layer.shadowRadius = 0.5
btn.layer.shadowOpacity = 0.5
btn.layer.shadowOffset = CGSize(width: 0.5, height: 0.5)
I'm setting the button background's to white, and changing the font color. it works for ALL of them. However, the shadow/opacity is only working for the last 3 rows... but I tried changing the "Q" to "F" to make sure that that btn is being iterated over, which it definitely is as you can see in the picture:
here's the full function:
func setButtonUI (containerView: UIStackView) {
for view in containerView.subviews {
if let btn = view as? UIButton {
btn.layer.cornerRadius = 10
btn.setTitleColor(UIColor(red: 0.0/255.0, green: 51.0/255.0, blue: 102.0/255.0, alpha: 1.0), for: .normal)
btn.layer.backgroundColor = UIColor.white.cgColor
//shadows (working for all but first row)
btn.layer.shadowRadius = 0.5
btn.layer.shadowOpacity = 0.5
btn.layer.shadowOffset = CGSize(width: 0.5, height: 0.5)
if btn.currentTitle == "Q" {
btn.setTitle("F", for: .normal)
}
}
}
}
any ideas as to why the first row is not getting the shadow effects?

How would I change background color of alert view

I am working on tvOS project, I need to create custom alert view with particular background color and text.
Finally , I have got the solution,
if let next = context.nextFocusedView as? UIButton {
next.setTitleColor(UIColor.blackColor(), forState: UIControlState.Focused)
next.backgroundColor = UIColor(red: 248/255, green: 175/255, blue: 2/255, alpha: 1.0)

Resources