Didn't tapped on textfield - ios

I create programmatically custom textfield
import UIKit
class SearchTextField: UITextField, UITextFieldDelegate {
let padding = UIEdgeInsets(top: 0, left: 40, bottom: 0, right: 5);
init(frame: CGRect, tintText: String, tintFont: UIFont, tintTextColor: UIColor) {
super.init(frame:frame)
self.frame = frame
delegate = self
backgroundColor = .white
textColor = tintTextColor
placeholder = tintText
font = tintFont
createBorder()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
delegate = self
}
func createBorder() {
self.layer.cornerRadius = 6
self.layer.borderColor = UIColor(red: 169/255, green: 169/255, blue: 169/255, alpha: 1).cgColor
self.layer.borderWidth = 1
}
override func textRect(forBounds bounds: CGRect) -> CGRect {
return UIEdgeInsetsInsetRect(bounds, padding)
}
override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
return UIEdgeInsetsInsetRect(bounds, padding)
}
override func editingRect(forBounds bounds: CGRect) -> CGRect {
return UIEdgeInsetsInsetRect(bounds, padding)
}
}
and add it like a subview to my view which is a subview of Google maps view
import UIKit
import GoogleMaps
class MapViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var mapView: GMSMapView!
var customSearchBar: SearchTextField!
let searchBarTextColor = UIColor(red: 206, green: 206, blue: 206, alpha: 1)
override func viewDidLoad() {
super.viewDidLoad()
let camera = GMSCameraPosition.camera(withLatitude: 55.75, longitude: 37.62, zoom: 13.0)
mapView.camera = camera
mapView.isUserInteractionEnabled = true
addTopBarView(mapView: mapView)
}
func addTopBarView(mapView: GMSMapView) {
//heigt of topBar is 14% of height of view^ width is the same
let topBarFrame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height * 0.14)
let topBarView = UIView(frame: topBarFrame)
addTopBarViewBackground(view: topBarView)
addTitleForTopBarView(view: topBarView)
addProfileIconForTopBarView(view: topBarView)
addSettingsIconForTopBarView(view: topBarView)
addSearchBar(view: topBarView)
topBarView.isUserInteractionEnabled = true
mapView.addSubview(topBarView)
}
func addSearchBar(view: UIView) {
let frameCustomSearchBar = CGRect(x: 10, y: 45, width: view.frame.width - 20, height: 40)
let fontCustomSearchBar = UIFont(name: "HelveticaNeueCyr", size: 28) ?? UIFont.italicSystemFont(ofSize: 14)
let textColorCustomSearchBar = UIColor(red: 206/255, green: 206/255, blue: 206/255, alpha: 1)
customSearchBar = SearchTextField(frame: frameCustomSearchBar, tintText: NSLocalizedString("find_petrole", comment: ""), tintFont: fontCustomSearchBar, tintTextColor: textColorCustomSearchBar)
customSearchBar.delegate = self
customSearchBar.isUserInteractionEnabled = true
customSearchBar.isEnabled = true
let iconPinView = UIImageView(image: #imageLiteral(resourceName: "icon_pin"))
iconPinView.frame = CGRect(x: 10, y: 10, width: 12, height: 20)
customSearchBar.addSubview(iconPinView)
let iconAddView = UIImageView(image: #imageLiteral(resourceName: "icon_add"))
iconAddView.frame = CGRect(x: customSearchBar.frame.width - 34, y: 10, width: 20, height: 20)
customSearchBar.addSubview(iconAddView)
view.addSubview(customSearchBar)
}
The textfield(customSearchBar) i see but it doesn't clickable, when i tapped on it nothing happens. I saw a few such problems here but did not find anything that help me.

You need inspect UIView Hierarchy using View Debugging feature of xcode and you need to check that textfield does not overlap with other view.
Run the app. View Debugging works in the simulator and on devices, but it's important to note that it needs to be an iOS 8 simulator or device. That said, you may allow earlier deployment targets in your project, just make sure you run on iOS 8 when you try View Debugging.
Navigate to the screen/view that you want to inspect within the running app.
In the Navigators Panel (left column), select the Debug Navigator (sixth tab). Next to your process, you'll see two buttons – press the rightmost button and select View UI Hierarchy

I guess it's because you put the UITextField under other touchable views so the touch event was intercepted.
if you make the custom textField hierarchy by a non-defalut isUserInteractionEnabled object, remember to enable it.

Related

when using CHTWaterfallLayout ,In My collection view cell , subview is not placing properly specially Y co-ordinate.scrolling makes it worse

this is the code where i am configuring the cell.
cell.configure(image: models[indexPath.item].image, tagText: models[indexPath.item].tag, priceIcon: models[indexPath.item].priceIcon, value: models[indexPath.item].price)
and this is my code for cell.
//
// ImageCollectionViewCell.swift
// tr0ve-iOSApp
//
//
//
// ImageCollectionViewCell.swift
// MyCollectionView
//
import UIKit
class ImageCollectionViewCell: UICollectionViewCell {
static let identifier = "ImageCollectionViewCell"
let itemView = UIView()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(itemView)
contentView.clipsToBounds = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
itemView.frame = contentView.bounds
}
override func prepareForReuse() {
super.prepareForReuse()
itemView.subviews.forEach { view in
view.removeFromSuperview()
}
}
func configure (image: UIImage?, tagText: String, priceIcon: UIImage, value: Float){
let imageView = UIImageView(image: image)
let priceTagView = UIView(frame: CGRect(x: 5, y: contentView.frame.size.height-50, width: 60, height: 20))
priceTagView.backgroundColor = .black
let valueLabel = UILabel(frame: CGRect(x: 20, y: 5, width: 35, height: 10))
valueLabel.textColor = .white
valueLabel.text = String(value)
valueLabel.font = UIFont.systemFont(ofSize: 12, weight: .regular)
let priceIconView = UIImageView(frame: CGRect(x: 5, y: 5, width: 10, height: 10))
priceIconView.image = priceIcon
priceTagView.addSubview(priceIconView)
priceTagView.addSubview(valueLabel)
let tag = UILabel(frame: CGRect(x: 100, y: contentView.frame.size.height-50, width: 20, height: 20))
tag.text = tagText
tag.textColor = .white
tag.textAlignment = .center
if tagText == "UC" {
tag.backgroundColor = .green
}
else {
tag.backgroundColor = .blue
}
itemView.addSubview(imageView)
itemView.addSubview(priceTagView)
itemView.addSubview(tag)
}
}
[in this image i want to add subview in cell's bottom, and in tried it using image's frame and by contentView's frame. but it is doing good for some cells and bad for the other ones. and when i scroll everyhing meshes up.1

Extension causing issue with clear button in Swift

I'm using a placeHolder extension to give padding to the placeholder. But when I apply this class to my input field it doesn't show the clear button even if I select "Appears while editing" on the storyboard.
Can someone tell me how to fix it?
import UIKit
class textFiledplaceholder: UITextField {
static let font_size : CGFloat = 16
static let leftPadding : CGFloat = 15
static let righPadding : CGFloat = 15
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
self.comminIt()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.comminIt()
}
func comminIt()
{
borderStyle = .none
backgroundColor = .white
// layer.masksToBounds = true
setLeftPaddingPoints(textFiledplaceholder.leftPadding)
setRightPaddingPoints(textFiledplaceholder.righPadding)
}
}
extension UITextField {
func setLeftPaddingPoints(_ amount:CGFloat){
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: amount, height: self.frame.size.height))
self.leftView = paddingView
self.leftViewMode = .always
}
func setRightPaddingPoints(_ amount:CGFloat) {
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: amount, height: self.frame.size.height))
self.rightView = paddingView
self.rightViewMode = .always
}
}
You can not use rightview and clearbutton together. And if you are going to use a clear button then I don't think there is any use of right padding. Remove right padding and it will resolve your issue.

addTarget on a Custom UI Button not working programmatically

I created a custom UIButton with this initialiser :
class CustomButton : UIButton{
override init(frame: CGRect) {
super.init(frame: frame)
setUpButtoninClass(frame)
addTarget(self, action: #selector(handleTap), for:.touchUpInside )
}
fileprivate func setUpButtoninClass(_ frame: CGRect) {
let padding : CGFloat = 16
self.frame = frame
layer.shadowColor = UIColor.darkGray.cgColor
layer.shadowOpacity = 0.3
layer.shadowOffset = .zero
layer.shadowRadius = 10
layer.cornerRadius = frame.width/2
backgroundColor = UIColor(white: 0.9, alpha: 1)
let buttonView = UIView(frame: frame)
buttonView.layer.cornerRadius = frame.width/2
buttonView.backgroundColor = .white
addSubview(buttonView)
let imageView = UIImageView(image: UIImage(named: "pen")?.withRenderingMode(.alwaysTemplate))
imageView.tintColor = UIColor(white: 0.7, alpha: 1)
buttonView.addSubview(imageView)
imageView.anchor(top: buttonView.topAnchor, leading: buttonView.leadingAnchor, bottom: buttonView.bottomAnchor, trailing: buttonView.trailingAnchor, padding: UIEdgeInsets.init(top: padding, left: padding, bottom: padding, right: padding))
}
#objc func handleTap(){
print("I'm here")
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}}
In the initialiser I'm adding a target but when I actually initialise the custom button in the VC the #selector method (handleTap) is not called.
This is the implementation of custom Button in VC:
class ViewController: UIViewController {
let circularButton = CustomButton(frame: CGRect(x: 0, y: 0, width: 70, height: 70))
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(circularButton)
circularButton.center = view.center
}
I also tried to add the target when initialising the CustomButton in the VC but nothing changed.
I would like to know where I'm making a mistake in setting up the button.
EDIT 1 :
this is the Debug View Hierarchy
OMG, after debug your code, buttonView and imageView is on the top. Button is behide. You can set the color to debug it more easily. Delete 2 views above make your code works perfectly
I think it's your fault here,
Touch is not detected because you added an ImageView to the top of UIButton.
Try this, or this one,
buttonView.isUserInteractionEnabled = true
imageView.isUserInteractionEnabled = true

iOS 11 - Unable to change Navigation Bar height

I am working on an application and I just upgraded to Xcode 9 / Swift 4 and also upgraded my iPhone to iOS 11.
The application was installed when I installed iOS 11 and all seemed OK until I run it from Xcode. Now I am stuck with the default NavBar height.
The code I was using to change the height is no longer working:
class CustomNavControllerVC: UINavigationController
{
let navBarHeight : CGFloat = 64.0
let navbarBackButtonColor = UIColor(red: 247/255, green: 179/255, blue: 20/255, alpha: 1)
override func viewDidLoad()
{
super.viewDidLoad()
print("CustomNavControllerVC > viewDidLoad")
}
override func viewDidLayoutSubviews()
{
print("CustomNavControllerVC > viewDidLayoutSubviews")
super.viewDidLayoutSubviews()
navigationBar.frame.size.height = navBarHeight
navigationBar.tintColor = navbarBackButtonColor
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
// In my VCs
override func viewDidLoad()
{
customizeNavBar()
}
func customizeNavBar()
{
let navbarBackItem = UIBarButtonItem()
navbarBackItem.title = "Înapoi"
navigationItem.backBarButtonItem = navbarBackItem
let navbarImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 55, height: 20))
navbarImageView.contentMode = .scaleToFill
let navbarLogo = UIImage(named: "NavBarLogo.png")
navbarImageView.image = navbarLogo
navigationItem.titleView = navbarImageView
}
So far the only thing I could find on this issue is this:
iOS 11 navigation bar height customizing
iOS11 customize navigation bar height
How to correctly set UINavigationBar height in iOS 11
But the info provided does not help, unfortunately.
Any ideas / suggestions?
Updated 2017.10.6
I had the same problem. Below is my solution. I assume that height size is 66.
My solution is working fine iOS 10, 11.
Please choose my answer if it helps you.
Create NavgationBar.swift
import UIKit
class NavigationBar: UINavigationBar {
//set NavigationBar's height
var customHeight : CGFloat = 66
override func sizeThatFits(_ size: CGSize) -> CGSize {
return CGSize(width: UIScreen.main.bounds.width, height: customHeight)
}
override func layoutSubviews() {
super.layoutSubviews()
frame = CGRect(x: frame.origin.x, y: 0, width: frame.size.width, height: customHeight)
// title position (statusbar height / 2)
setTitleVerticalPositionAdjustment(-10, for: UIBarMetrics.default)
for subview in self.subviews {
var stringFromClass = NSStringFromClass(subview.classForCoder)
if stringFromClass.contains("BarBackground") {
subview.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: customHeight)
subview.backgroundColor = .yellow
}
stringFromClass = NSStringFromClass(subview.classForCoder)
if stringFromClass.contains("BarContent") {
subview.frame = CGRect(x: subview.frame.origin.x, y: 20, width: subview.frame.width, height: customHeight - 20)
subview.backgroundColor = UIColor(red: 20/255, green: 20/255, blue: 20/255, alpha: 0.4)
}
}
}
}
Set Storyboard
Set Custom NavigationBar class
Add TestView + Set SafeArea
ViewController.swift
import UIKit
class ViewController: UIViewController {
var navbar : UINavigationBar!
#IBOutlet weak var testView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
//update NavigationBar's frame
self.navigationController?.navigationBar.sizeToFit()
print("NavigationBar Frame : \(String(describing: self.navigationController!.navigationBar.frame))")
}
//Hide Statusbar
override var prefersStatusBarHidden: Bool {
return true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(false)
//Important!
if #available(iOS 11.0, *) {
//Default NavigationBar Height is 44. Custom NavigationBar Height is 66. So We should set additionalSafeAreaInsets to 66-44 = 22
self.additionalSafeAreaInsets.top = 22
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
SecondViewController.swift
import UIKit
class SecondViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// Create BackButton
var backButton: UIBarButtonItem!
let backImage = imageFromText("Back", font: UIFont.systemFont(ofSize: 16), maxWidth: 1000, color:UIColor.white)
backButton = UIBarButtonItem(image: backImage, style: UIBarButtonItemStyle.plain, target: self, action: #selector(SecondViewController.back(_:)))
self.navigationItem.leftBarButtonItem = backButton
self.navigationItem.leftBarButtonItem?.setBackgroundVerticalPositionAdjustment(-10, for: UIBarMetrics.default)
}
override var prefersStatusBarHidden: Bool {
return true
}
#objc func back(_ sender: UITabBarItem){
self.navigationController?.popViewController(animated: true)
}
//Helper Function : Get String CGSize
func sizeOfAttributeString(_ str: NSAttributedString, maxWidth: CGFloat) -> CGSize {
let size = str.boundingRect(with: CGSize(width: maxWidth, height: 1000), options:(NSStringDrawingOptions.usesLineFragmentOrigin), context:nil).size
return size
}
//Helper Function : Convert String to UIImage
func imageFromText(_ text:NSString, font:UIFont, maxWidth:CGFloat, color:UIColor) -> UIImage
{
let paragraph = NSMutableParagraphStyle()
paragraph.lineBreakMode = NSLineBreakMode.byWordWrapping
paragraph.alignment = .center // potentially this can be an input param too, but i guess in most use cases we want center align
let attributedString = NSAttributedString(string: text as String, attributes: [NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: color, NSAttributedStringKey.paragraphStyle:paragraph])
let size = sizeOfAttributeString(attributedString, maxWidth: maxWidth)
UIGraphicsBeginImageContextWithOptions(size, false , 0.0)
attributedString.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Yellow is barbackgroundView. Black opacity is BarContentView.
And I removed BarContentView's backgroundColor.
That's It.

UIView animation causing label to twitch

I have an IconView class that I use as a custom image for a Google Maps marker. All of the print statements show that the code is correctly executing. However, the "12:08" UILabel in circleView keeps on growing and shrinking (i.e. twitching). I can't figure out what the problem might be. I've tried manually setting the the font in the completion block, commenting out the adjustsFontSizeToFitWidth, changing the circleView to a UIButton.
import UIKit
class IconView: UIView {
var timeLabel: UILabel!
var circleView: UIView!
var clicked: Bool!
//constants
let circleViewWidth = 50.0
let circleViewHeight = 50.0
override init(frame:CGRect) {
super.init(frame : frame)
self.backgroundColor = UIColor(red: 47/255, green: 49/255, blue: 53/255, alpha: 0.0)
clicked = false
if !clicked {
//MAIN CIRCLE
print("init circle view")
circleView = UIView(frame: CGRect(x:0, y:0, width:circleViewWidth, height:circleViewHeight))
circleView.backgroundColor = UIColor(red: 47/255, green: 49/255, blue: 53/255, alpha: 1.0)
circleView.layer.cornerRadius = circleView.frame.size.height / 2.0
circleView.layer.masksToBounds = true
self.addSubview(circleView)
timeLabel = UILabel(frame: CGRect(x: 0, y: 0, width: circleViewWidth, height: circleViewHeight/3.0))
timeLabel.center = circleView.center
timeLabel.text = "12:08"
timeLabel.textAlignment = .center
timeLabel.textColor = .white
timeLabel.numberOfLines = 0
timeLabel.font = UIFont.systemFont(ofSize: 11)
timeLabel.font = UIFont.boldSystemFont(ofSize: 11)
timeLabel.adjustsFontSizeToFitWidth = true
circleView.addSubview(timeLabel)
}
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
let iconView = marker.iconView as! IconView
print("going to start animating")
if !iconView.clicked {
UIView.animate(withDuration: 0.2, animations: {
print("making this bigger now")
iconView.circleView.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
})
{ (finished:Bool) -> Void in
print("DONE")
iconView.clicked = true
}
}
return true
}

Resources