I am trying to show 3 radio buttons. If Button 1 was selected remaining 2 should be disabled. If button 2 is selected, button 1 and 3 should be disabled. and last if button 3 is selected 1 and 2 should be disabled. I tried to do in multiple ways.but not succeeded. Here is my code any help is appreciated.
#IBAction func button1Clicked(_ sender: UIButton) {
if button2.isSelected {
button2.isSelected = false
button1.isSelected = true
} else {
button1.isSelected = true
}
}
#IBAction func button2Clicked(_ sender: UIButton) {
if button1.isSelected {
button1.isSelected = false
button2.isSelected = true
} else {
button2.isSelected = true
}
}
#IBAction func button3Clicked(_ sender: UIButton) {
if button3.isSelected {
button3.isSelected = false
button2.isSelected = true
//button1.isSelected = true
} else {
button1.isSelected = true
}
}
you can try like this way by changing UIImage of button:
#IBAction func mr(_ sender: Any) {
mrOutlet.setImage(UIImage(named: "check"), for: .normal)
msOutlet.setImage(UIImage(named: "uncheck"), for: .normal)
mrsOutlet.setImage(UIImage(named: "uncheck"), for: .normal)
salutation = "Mr."
}
#IBAction func ms(_ sender: Any) {
msOutlet.setImage(UIImage(named: "check"), for: .normal)
mrOutlet.setImage(UIImage(named: "uncheck"), for: .normal)
mrsOutlet.setImage(UIImage(named: "uncheck"), for: .normal)
salutation = "Ms."
}
#IBAction func mrs(_ sender: Any) {
mrsOutlet.setImage(UIImage(named: "check"), for: .normal)
mrOutlet.setImage(UIImage(named: "uncheck"), for: .normal)
msOutlet.setImage(UIImage(named: "uncheck"), for: .normal)
salutation = "Mrs."
}
Hope this help :)
Related
While i'm doing collection view reload data below method was calling at a time for 100 times because of my array having 100.but when i am using in story board it call for 5 times then i scroll it then it is calling. ineed to work it as storyboard in xib.loading from xib and code s mentioned below.
override func viewDidLoad() {
super.viewDidLoad()
self.clvProducts.register(UINib(nibName: "ProductListCell", bundle: nil), forCellWithReuseIdentifier: "ProductListCell")
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == clvProducts {
var cell:ProductListCell? = collectionView.dequeueReusableCell(withReuseIdentifier: "ProductListCell", for: indexPath as IndexPath) as? ProductListCell
if (cell == nil) {
let nib: NSArray = Bundle.main.loadNibNamed("ProductListCell", owner: self, options: nil)! as NSArray
cell = (nib.object(at: 0) as! ProductListCell)
}
if let url = NSURL(string: ((self.objCategorywiseResponse.SimilirProductsList![indexPath.row].productPic)!)) {
// cell?.imgProduct.sd_setImage(with: url as URL, placeholderImage: UIImage(named: "placeholder.png"))
cell?.imgProduct.kf.setImage(with: url as URL)
}
if let intRating = self.objCategorywiseResponse.SimilirProductsList![indexPath.row].AvgRatingCount {
cell?.subViewRating.rating = intRating
}
if let strShopName = self.objCategorywiseResponse.SimilirProductsList![indexPath.row].ShopName {
cell?.lblShopName.text = strShopName
}
if let strDisctance = self.objCategorywiseResponse.SimilirProductsList![indexPath.row].Distance {
cell?.lblDistance.setTitle("\(strDisctance) km near by you", for: .normal)
}
if let strLandLineNo = self.objCategorywiseResponse.SimilirProductsList![indexPath.row].LandLineNumber {
cell?.lblMobileNo.text = "\(strLandLineNo)"
}
cell?.btnAddToCompare.tag = indexPath.row
cell?.btnAddToCompare.addTarget(self, action: #selector(btnClickedAddToCompare(_:)), for: .touchUpInside)
cell?.btnAddProduct.tag = indexPath.row
cell?.btnAddProduct.addTarget(self, action: #selector(btnClickedAddProduct(_:)), for: .touchUpInside)
cell?.btnCall.tag = indexPath.row
cell?.btnCall.addTarget(self, action: #selector(self.callCellactn(_:)), for: .touchUpInside)
cell?.btnMap.tag = indexPath.row
cell?.btnMap.addTarget(self, action: #selector(self.locationCellactn(_:)), for: .touchUpInside)
return cell!
}
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if collectionView == clvProducts {
if indexPath.row == ((self.objCategorywiseResponseStage1).count - 1)
{
print("came to last row")
// self.moreData()
}
}
}
UICollectionView is a subclass of the UIScrollView, try using the scrollview method scrollViewDidEndDecelerating
override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let bottom = scrollView.contentOffset.y + scrollView.frame.size.height
if bottom >= scrollView.contentSize.height {
print("came to last row")
//self.moreData()
}
}
I have a View with an UIImageView that I want to be 'selectable' so that the user can pick a new image.
The function for picking the new image is in the Controller.
Question
How do I call the myDatasourceController.handleTap() function by pressing the ImageView, so that the image picker is presented?
This is an example of my current setup
View
class myView: UICollectionViewCell {
lazy var profileImageView: UIImageView = {
let iv = UIImageView()
iv.isUserInteractionEnabled = true
iv.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(myDatasourceController.handleTap)))
return iv
}()
}
Controller
class myDatasourceController: UICollectionViewController,
UICollectionViewDelegateFlowLayout, UIImagePickerControllerDelegate,
UINavigationControllerDelegate {
func handleTap(){
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.allowsEditing = true
present(imagePickerController, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
// logic for picking the image
dismiss(animated: true, completion: nil)
}
}
This setup currently throws the error
unrecognized selector sent to instance 0x7f9163d493f0
which has led me to try various combinations of
handleTap(_:)
handleTap(sender: UITapGestureRecogniser)
/// etc
but I can't get any of them to work. How should I be constructing my View, Controller, and the interaction between them to present the image picker?
Use Like this
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(RegisterViewController. handleTap(gesture:)))
func handleTap(gesture: UIGestureRecognizer) {
// if the tapped view is a UIImageView then set it to imageview
if (gesture.view as? UIImageView) != nil {
print("Image Tapped")
picker.allowsEditing = false
picker.sourceType = .photoLibrary
picker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
present(picker, animated: true, completion: nil)
}
}
Use like this :
myDatasourceController.handleTap()
In your code :
iv.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(myDatasourceController.handleTap())))
The key to the solution is to implement a protocol / delegate, as suggested by #Akis
I've uploaded the full project to my github account. The key code is copied here.
View Controller
protocol ImagePickerDelegate: class {
func loadImagePicker()
}
class HomeViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout, UIImagePickerControllerDelegate, UINavigationControllerDelegate, ImagePickerDelegate {
let cellId = "cellId"
func loadImagePicker(){
print(" -- image picker -- ")
// load image picker
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.allowsEditing = true
present(imagePickerController, animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
// get the image
var selectedImageFromPicker: UIImage?
if let editedImage = info["UIImagePickerControllerEditedImage"] as? UIImage {
selectedImageFromPicker = editedImage
}else if let originalImage = info["UIImagePickerControllerOriginalImage"] as? UIImage {
selectedImageFromPicker = originalImage
}
if let selectedImage = selectedImageFromPicker {
//doSomethingWithTheImage(image: selectedImage)
}
dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.backgroundColor = .black
collectionView?.register(HomeView.self, forCellWithReuseIdentifier: cellId)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! HomeView
cell.delegate = self
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: view.frame.height)
}
}
View
class HomeView: UICollectionViewCell {
// break retain cycle with weak var
weak var delegate: ImagePickerDelegate?
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
lazy var profileImageView: UIImageView = {
let iv = UIImageView()
iv.isUserInteractionEnabled = true
iv.image = UIImage(named: "kuang-si-falls-waterfall-water-laos-50588.jpg")
iv.contentMode = .scaleAspectFill
let tap = UITapGestureRecognizer(target: self, action: #selector(loadImagePicker))
iv.addGestureRecognizer(tap)
return iv
}()
func loadImagePicker() {
delegate?.loadImagePicker()
print(" imagePickerProtocol called ")
}
func setupViews() {
backgroundColor = .white
addSubview(profileImageView)
profileImageView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
profileImageView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
profileImageView.frame = CGRect(x: 0, y: 0, width: 150, height: 150)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
I have 5 UITextFields, everytime I clicked on the textfield, keyboard appeared. when user touch outside of the textfield, keyboard will hide. However, there is one special textField is for Pop Up. When Pop up appear, the previous textfield couldn't hide the keyboard. How am I gonna hide the keyboard first, and then show the pop up?
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField == self.customerAddress{
scrollView.setContentOffset(CGPoint(x: 0,y:5), animated: true)
}
else if textField == self.district{
textField.resignFirstResponder()
scrollView.setContentOffset(CGPoint(x: 0,y:20), animated: true)
visualEffectView.isHidden = false
districtpicker.selectRow(3, inComponent: 0, animated: false)
self.view.addSubview(districtPopUp)
districtPopUp.center = self.subView.convert(CGPoint(x:subView.frame.size.width/2,y:subView.frame.size.height/3), to: subView)
districtPopUp.transform = CGAffineTransform.init(scaleX: 1.3, y: 1.3)
UIView.animate(withDuration: 0.4, animations: {
self.visualEffectView.alpha = 0.5
self.districtPopUp.alpha = 1
self.districtPopUp.transform = CGAffineTransform.identity
})
}
}
#IBAction func districtPopDismiss(_ sender: UIButton) {
scrollView.setContentOffset(CGPoint(x: 0,y:-64), animated: true)
UIView.animate(withDuration: 0.3, animations: {
self.districtPopUp.transform = CGAffineTransform.init(scaleX: 1.3, y: 1.3)
self.visualEffectView.alpha = 1
}) { (success) in
self.districtPopUp.removeFromSuperview()
}
self.visualEffectView.isHidden = true
}
func textFieldDidEndEditing(_ textField: UITextField) {
textField.resignFirstResponder()
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
scrollView.setContentOffset(CGPoint(x: 0,y:-64), animated: true)
textField.resignFirstResponder()
return true
}
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(CustomerViewController.hideKeyboard))
subView.addGestureRecognizer(tapGesture)
visualEffectView.isHidden = true
self.customerName.delegate = self
self.customerAddress.delegate = self
self.customerContact.delegate = self
self.customerIC.delegate = self
self.ticketNumber.delegate = self
self.latitudeGPS.delegate = self
self.longitudeGPS.delegate = self
self.district.delegate = self
// Do any additional setup after loading the view.
}
func hideKeyboard(){
scrollView.setContentOffset(CGPoint(x: 0,y:-64), animated: true)
self.customerName.resignFirstResponder()
self.customerAddress.resignFirstResponder()
self.customerContact.resignFirstResponder()
self.customerIC.resignFirstResponder()
self.ticketNumber.resignFirstResponder()
self.latitudeGPS.resignFirstResponder()
self.longitudeGPS.resignFirstResponder()
self.district.resignFirstResponder()
}
Instead of invoking resignFirstResponder() on each of your textFields you can just invoke view.endEditing(true) and keyboard will hide. Try to invoke this before the logic responsible for presenting the popup.
Simple and easy for all view controller swift 3+
This code help you to hide keyboard on touch anywhere on viewcontrol
extension UIViewController {
func hideKeyboardWhenTappedAround() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
#objc func dismissKeyboard() {
view.endEditing(true)
}
}
Use below code in your viewDidLoad
self.hideKeyboardWhenTappedAround()
Hi I had switch from swift 2 to swift 3.
Here is my uploadVC
class PhotoUploadVC: UICollectionViewController {
fileprivate var assets: PHFetchResult<AnyObject>?
fileprivate var sideSize: CGFloat!
//It is snippet of viewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
//Navigation Config
self.navigationItem.title = "CAMERA ROLL"
if PHPhotoLibrary.authorizationStatus() == .authorized {
reloadAssets()
} else {
PHPhotoLibrary.requestAuthorization({ (status: PHAuthorizationStatus) -> Void in
if status == .authorized {
self.reloadAssets()
} else {
self.showNeedAccessMessage()
}
})
}
}
//Here is function about fetch images
fileprivate func showNeedAccessMessage() {
let alert = UIAlertController(title: "Image picker", message: "App need get access to photos", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (action: UIAlertAction) -> Void in
self.dismiss(animated: true, completion: nil)
}))
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action: UIAlertAction) -> Void in
UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
}))
self.show(alert, sender: nil)
}
fileprivate func reloadAssets() {
// activityIndicator.startAnimating()
assets = nil
collectionView?.reloadData()
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
assets = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: fetchOptions)
collectionView?.reloadData()
// activityIndicator.stopAnimating()
}
I got an error message above.
Where is problem?
I think "fileprivate var assets: PHFetchResult?"
Anyone helping me?
Try changing:
fileprivate var assets: PHFetchResult<AnyObject>?
into
var assets: [AnyObject]!
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)
}
}