I have a class called PickerFilterClass that access the YNDropDownView library and in there I create a pickerview in PickerFilterClass's extension. I want to the pickerview help sort a collectionview in another class called RestaurantDetails. I am trying to use the pickerview didselect function to access the collectionview called productCollection and reload the data when a user pickerview selects an row. I here is how I am trying to do this:
PickerFilter Class
class PickerFilterClass: YNDropDownView {
#IBOutlet var pickerView: UIPickerView!
var rotationAngle: CGFloat!
var filteredProducts = [Product]()
var products = [Product]()
let prodCollection: RestaurantDetails
let sections = [["Burgers", "Fries", "Cola", "Chicken", "Sides"],["Breakfast", "Lunch", "Dinner"]]
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.white
self.initViews()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.initViews()
}
#IBAction func confirmButtonClicked(_ sender: Any) {
self.normalSelected(at: 1)
self.hideMenu()
}
#IBAction func cancelButtonClicked(_ sender: Any) {
// self.changeMenu(title: "Changed", at: 1)
// self.changeMenu(title: "Changed", status: .selected, at: 0)
self.alwaysSelected(at: 1)
// self.alwaysSelected(at: 2)
// self.alwaysSelected(at: 3)
self.hideMenu()
}
override func dropDownViewOpened() {
print("Open Menu")
}
override func dropDownViewClosed() {
print("Close Menu")
}
func initViews() {
}
}
extension PickerFilterClass: UIPickerViewDataSource, UIPickerViewDelegate {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return sections[component].count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
pickerView.sizeToFit()
return sections[component][row]
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let view = UIView()
view.frame = CGRect(x: 10, y: 20, width: 300, height: 52)
let label = UILabel()
label.frame = CGRect(x: 0, y: 0, width: 300, height: 52)
label.textAlignment = .center
label.font = UIFont(name: "Tiny.Toon", size: 11)
label.textColor = UIColor.purple
label.text = sections[component][row]
view.addSubview(label)
// view rotation
// view.transform = CGAffineTransform(rotationAngle: 90 * (.pi/180))
return view
}
I am trying to use the pickerview to access this collection view here:
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
print(sections[row])
if sections.count > row {
let selectedUsage = sections[component][row].lowercased()
if (selectedUsage == RestaurantDetails.allProductIdentifier.lowercased()) {
filteredProducts = products
} else {
filteredProducts = products.filter { ($0.usage?.lowercased() ?? "") == selectedUsage }
}
self.prodCollection.productCollection.reloadData()
}
}
}
Related
my interface screenshot
I tried to set the width of a UIPickerView, but it didn't work.
For example, i used
class Coordinator : NSObject,UIPickerViewDelegate,UIPickerViewDataSource{
...
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let view = UIView(frame: CGRect(x:0,y:0,width:128,height:60))
...
return view
}
...
}
above code,could only change the width of the red block.
i want to change the width of the whole picker,including the half-opacity-block.
struct CustomPicker : UIViewRepresentable{
...
func makeUIView(context: UIViewRepresentableContext<CustomPicker>) -> UIPickerView {
let picker = UIPickerView(frame: CGRect(x: 0, y: 0, width: 50, height: 60))
return picker
}
}
above code didn't work .
In addition , is there some func could hide/remove/custom the half-opacity-mask ?
waiting for you help ! thx a lot :) !
Here's whole codes.
// ContentView
import SwiftUI
struct ContentView: View {
#State var selectedWeight : dataListItemModel = dataListItemModel(label: "1KG", value: 1)
#State var selectedTimes : dataListItemModel = dataListItemModel(label: "1RM", value: 1)
let timesDataList : [dataListItemModel] = [
dataListItemModel(label: "1RM", value: 1),
dataListItemModel(label: "2RM", value: 2),
dataListItemModel(label: "3RM", value: 3),
]
let weightDataList : [dataListItemModel] = [
dataListItemModel(label: "1.25KG", value: 1.25),
dataListItemModel(label: "2.5KG", value: 2.5),
dataListItemModel(label: "5KG", value: 5),
]
var body: some View {
HStack{
CustomPicker(selected: self.$selectedWeight,dataList: weightDataList,width: 200)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
// CustomPicker
import SwiftUI
import UIKit
struct dataListItemModel : Identifiable {
let id : String = UUID().uuidString
let label : String
let value : Double
init(label : String, value : Double) {
self.label = label
self.value = value
}
}
struct CustomPicker : UIViewRepresentable{
#Binding var selected : dataListItemModel
let dataList : [dataListItemModel]
let width : CGFloat
func makeCoordinator() -> CustomPicker.Coordinator {
return CustomPicker.Coordinator(parent1: self)
}
func makeUIView(context: UIViewRepresentableContext<CustomPicker>) -> UIPickerView {
let picker = UIPickerView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width/3, height: 60))
picker.dataSource = context.coordinator
picker.delegate = context.coordinator
// picker.autoresizingMask = [.flexibleWidth, .flexibleHeight]
return picker
}
func updateUIView(_ uiView: UIPickerView, context: UIViewRepresentableContext<CustomPicker>) {
}
class Coordinator : NSObject,UIPickerViewDelegate,UIPickerViewDataSource{
var parent : CustomPicker
let dataList : [dataListItemModel]
let width : CGFloat
init(parent1 : CustomPicker) {
parent = parent1
dataList = parent1.dataList
width = parent1.width
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return dataList.count
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
// pickerView.subviews.forEach({
// // $0.frame = CGRect(x:0,y:0,width:width,height:60)
//1
// $0.isHidden = $0.frame.height < 1.0
// })
return 1
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let view = UIView(frame: CGRect(x:0,y:0,width:width,height:60))
let label = UILabel(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height))
label.text = dataList[row].label
label.textColor = .white
label.textAlignment = .center
label.font = .systemFont(ofSize: 22,weight:.bold)
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 1
view.backgroundColor = .red
view.addSubview(label)
view.clipsToBounds = true
view.layer.cornerRadius = 8
return view
}
func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
return width
}
func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
return 60
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.parent.selected = dataList[row]
}
}
}
class Host : UIHostingController<ContentView>{
override var preferredStatusBarStyle: UIStatusBarStyle{
return .lightContent
}
}
Mine is an educational app, the student is given a word and then is supposed to select the corresponding image (say matching the word banana to the image of one, where the image is in a UIPickerview) However, my following code yields no results:
let possibleAnswers = [UIImage(named: Images.one), UIImage(named: Images.two), UIImage(named: Images.three), UIImage(named: Images.four)]
fileprivate let pickerView: UIPickerView = {
let pv = UIPickerView()
pv.translatesAutoresizingMaskIntoConstraints = false
return pv
}()
override func viewDidLoad() {
pickerView.delegate = self
pickerView.dataSource = self
}
extension ViewController: UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return possibleAnswers.count
}
}
extension ViewController: UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let myImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 220, height: 61))
myImageView.image = possibleAnswers[row]
return myImageView
}
}
Am I doing something wrong? How can I rectify this?
EDIT 1:
This is what the erroneous view looks like.
Set PickerView row Height to match your image size using rowHeightForComponent function
class ViewController: UIViewController,UITextFieldDelegate{
fileprivate let possibleAnswers:[UIImage] = [UIImage(named: "apple.png")!,UIImage(named: "banana.png")!,UIImage(named: "orange.png")!]
fileprivate var pickerView: UIPickerView?
fileprivate var toolBar:UIToolbar?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
view.addSubview(btn)
btn.translatesAutoresizingMaskIntoConstraints = false
btn.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
btn.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
btn.addTarget(self, action: #selector(test), for: .touchUpInside)
}
//MARK: Components
let btn :UIButton = {
let btn = UIButton(type: .system)
btn.setTitle("Select Correct Answer", for: .normal)
return btn
}()
}
// MARK: Pickerview Delegate
extension ViewController: UIPickerViewDelegate,UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return possibleAnswers.count
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let myImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
myImageView.image = possibleAnswers[row]
return myImageView
}
func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
return 100
}
}
//MARK: Functions
extension ViewController{
#objc func test(){
pickerView = UIPickerView.init()
pickerView!.delegate = self
pickerView!.backgroundColor = UIColor.white
pickerView!.setValue(UIColor.black, forKey: "textColor")
pickerView!.autoresizingMask = .flexibleWidth
pickerView!.contentMode = .center
pickerView!.frame = CGRect.init(x: 0.0, y: UIScreen.main.bounds.size.height - 300, width: UIScreen.main.bounds.size.width, height: 300)
self.view.addSubview(pickerView!)
toolBar = UIToolbar.init(frame: CGRect.init(x: 0.0, y: UIScreen.main.bounds.size.height - 300, width: UIScreen.main.bounds.size.width, height: 50))
toolBar!.barStyle = .blackTranslucent
toolBar!.items = [UIBarButtonItem.init(title: "Done", style: .done, target: self, action: nil)]
self.view.addSubview(toolBar!)
}
}
My pickerView was going very well, but don't know why just get wrong behavior after rebuild the project folder.
The component[0] will reload itself but I didn't write any code for it!
Below are the codes:
DropdownListExtension.swift
extension UITextField: UITextFieldDelegate {
func loadAddressDropdownData(data: [String], zipField: UITextField!) {
self.inputView = AddressPickerView(pickerData: data, cityField: self, zipField: zipField)
// ToolBar
let toolBar = UIToolbar()
// Adding Button ToolBar
// ...Init ToolBar
self.inputAccessoryView = toolBar
}
#objc func doneClick() {
self.resignFirstResponder()
}
#objc func cancelClick() {
self.resignFirstResponder()
}
}
AddressPickerView.swift
class AddressPickerView : UIPickerView, UIPickerViewDataSource, UIPickerViewDelegate {
var pickerData : [String]!
var pickerTextField : UITextField!
var zipTextField: UITextField!
var selectedRow = 0
var selectedCity = "臺北市"
init(pickerData: [String], cityField: UITextField, zipField: UITextField) {
super.init(frame: CGRect.zero)
self.pickerData = pickerData
self.pickerTextField = cityField
self.zipTextField = zipField
self.delegate = self
self.dataSource = self
DispatchQueue.main.async{
if pickerData.count > 0 {
self.pickerTextField.text = self.pickerData[0]
} else {
self.pickerTextField.text = nil
}
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0{
return pickerData.count
}else {
switch selectedCity{
//...
default:
return 0
}
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0{
return pickerData[row]
} else {
switch selectedCity{
//...
default:
return ""
}
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
print(component)
if component == 0 {
pickerTextField.text = pickerData[row]
selectedRow = row
selectedCity = pickerData[row]
pickerView.reloadComponent(1)
}else {
switch selectedCity{
case "臺北市":
zipTextField.text = taipei[row]
case "基隆市":
zipTextField.text = keelung[row]
//...
default:
return print("")
}
}
}
}
Please help me for fix it, I spent almost 3 das but still cannot figure out the problem...
I want to show a UIPickerView when tapping a UITextField.
And I made a 'place' UITextField with a UIPickerView.
But, I don't know how to make another UITextField with a UIPickerView.
I tried to use 'switch', but UITextField was not a value, so I couldn't do it with 'switch'.
I want to change UIPickerViewData when I select the different UITextField.
How can I do?
Here's the codes.
Thank you!
#IBOutlet weak var place: UITextField!
#IBOutlet weak var product: UITextField!
#IBOutlet weak var number: UITextField!
let placeArray = ["A", "B", "C", "D", "E", "F"]
let productArray = ["Apple", "Banana", "Grape"]
let numberArray = ["1", "2", "3", "4", "5", "6"]
var pickerView = UIPickerView()
var textField: UITextField!
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return placeArray.count
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
place.text = placeArray[row]
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return placeArray[row]
}
override func viewDidLoad() {
super.viewDidLoad()
pickerView.delegate = self
pickerView.dataSource = self
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(displayPickerView))
tapGesture.numberOfTapsRequired = 1
place.addGestureRecognizer(tapGesture)
}
#objc private func displayPickerView() {
if textField == nil {
self.textField = UITextField(frame: .zero)
textField.inputView = self.pickerView
self.view.addSubview(textField)
}
textField.becomeFirstResponder()
}
Very simple way to do this.
var placePickerView = UIPickerView()
var productPickerView = UIPickerView()
var numberPickerView = UIPickerView()
override func viewDidLoad() {
super.viewDidLoad()
placePickerView.delegate = self
placePickerView.dataSource = self
place.inputView = placePickerView
productPickerView.delegate = self
productPickerView.dataSource = self
product.inputView = productPickerView
numberPickerView.delegate = self
numberPickerView.dataSource = self
number.inputView = numberPickerView
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
var numberOfRows: Int = 1
if pickerView == placePickerView {
numberOfRows = placeArray.count
} else if pickerView == productPickerView {
numberOfRows = productArray.count
} else if pickerView == numberPickerView {
numberOfRows = numberArray.count
}
return numberOfRows
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView == placePickerView {
place.text = placeArray[row]
} else if pickerView == productPickerView {
productType.text = productArray[row]
} else if pickerView == numberPickerView {
transactionType.text = numberArray[row]
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
var title: String?
if pickerView == placePickerView {
title = placeArray[row]
} else if pickerView == productPickerView {
title = productArray[row]
} else if pickerView == numberPickerView {
title = numberArray[row]
}
return title
}
// call class in UIViewController
label = TimePickerView()
alertController = UIAlertController(title: " \n\n\n\n\n\n\n\n\n\n", message: "", preferredStyle: UIAlertControllerStyle.alert)
alertController.view.addSubview(label)
// alertController.view.addSubview(samplePicker)
self.present(alertController, animated: true, completion: nil)
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
import UIKit
class TimePickerView: UIPickerView, UIPickerViewDataSource, UIPickerViewDelegate {
var hour:Int = 0
var minute:Int = 0
var samplePicker: UIPickerView = UIPickerView()
var sampleSegment:UISegmentedControl = UISegmentedControl ()
var alertController:UIAlertController = UIAlertController()
required internal init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
self.setup()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.setup()
}
func setup(){
self.delegate = self
self.dataSource = self
samplePicker = UIPickerView(frame: CGRect(x:10.0, y:40.0, width:10, height:150))
samplePicker.delegate = self
samplePicker.dataSource = self
samplePicker.showsSelectionIndicator = true
samplePicker.tintColor = UIColor.red
samplePicker.reloadAllComponents()
sampleSegment = UISegmentedControl(items: NSArray(object: "تایید") as [AnyObject])
sampleSegment.isMomentary = true
sampleSegment.frame = CGRect(x:0, y:0,width:270.0, height:30.0)
sampleSegment.tintColor = UIColor.black
sampleSegment.backgroundColor = UIColor.gray
sampleSegment.addTarget(self, action: #selector(TimePickerView.dismissAlert), for: UIControlEvents.valueChanged)
self.addSubview(sampleSegment)
self.addSubview(samplePicker)
}
public func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
switch component {
case 0:
self.hour = row
print(row)
case 1:
self.minute = row
default:
print("No component with number \(component)")
}
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0 {
return 24
}
return 60
}
private func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> Int {
return 30
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0 {
return String(row)
}else {
return String(row)
}
}
func dismissAlert(){
alertController.dismiss(animated: true, completion: nil)
}
}
Use AddAction, an instance property of UIAlertController.