martes, 27 de diciembre de 2016

iOS: Table view text field picker

// DownTableViewCell
import UIKit

class DownTableViewCell: UITableViewCell {

    override func awakeFromNib() {
        super.awakeFromNib()
       
        setup()
    }
   
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
       
        setup()
    }
   
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
       
        setup()
    }
       
    private func setup() {
       
        textLabel?.highlightedTextColor = UIButton().tintColor
        backgroundColor = UIColor(red: 208/255.0, green: 213/255.0, blue: 219/255.0, alpha: 1)
        selectedBackgroundView = createBackgroundView()
    }
   
    private func createBackgroundView() -> UIView {
       
        let backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height - 1))
        backgroundView.backgroundColor = UIColor(red: 208/255.0, green: 213/255.0, blue: 219/255.0, alpha: 1)
       
        return backgroundView
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        accessoryType = selected ? .checkmark : .none
    }
}

// DownTableView
import UIKit

class DownTableView: UIControl, UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate {
    
    var textField: UITextField!
    var shouldDisplayCancelButton: Bool = true
    var data: [ProductAttribute] = [ProductAttribute]()
    var selectedValuesString: String = ""
    var selectedValues: [ProductAttribute] = [ProductAttribute]()
    var previousSelectedValues: [ProductAttribute] = [ProductAttribute]()
    var tableView: UITableView?

    /*
    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) {
        // Drawing code
    }
    */
    
    init(textField: UITextField, withData data: [ProductAttribute]) {
        
        super.init(frame: CGRect.zero)
        
        self.textField = textField
        self.textField.delegate = self
        self.textField.placeholder = "Tap to choose..."
        self.textField.rightView = UIImageView(image: UIImage(named: "downArrow"))
        self.textField.rightView?.contentMode = UIViewContentMode.scaleAspectFit
        self.textField.rightView?.clipsToBounds = true
        self.textField.rightViewMode = UITextFieldViewMode.always
        
        self.data = data
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func showArrowImage(_ show:Bool) {
        self.textField.rightViewMode = show ? UITextFieldViewMode.always : UITextFieldViewMode.never
    }
    
    func doneClick(sender: Any?) {
        
        addAllSelectedValueToPrevious()
        
        textField.resignFirstResponder()
        
        if self.textField.text?.length == 0 {
            self.setValue(atIndex:-1)
            self.textField.placeholder = "Tap to choose..."
        }
        
        sendActions(for: UIControlEvents.valueChanged)
    }
    
    private func addAllSelectedValueToPrevious() {
        
        previousSelectedValues.removeAll()
        
        for value in selectedValues {
            previousSelectedValues.append(value)
        }
    }
    
    func cancelClicked(sender: Any?) {
        
        textField.resignFirstResponder()
        
        if previousSelectedValues.count == 0 {
            textField.placeholder = "Tap to choose..."
        }
        
        textField.text = toString(productsAttributes: previousSelectedValues)
    }
    
    func setValue(atIndex index:NSInteger) {
        
        if let tableView = self.tableView, index >= 0 {
            self.tableView(tableView, didSelectRowAt: IndexPath(item: index, section: 0))
        }
    }
    
    func showTableView(sender: Any?) {
        
        tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 320, height: 216))
        tableView?.allowsMultipleSelection = true
        tableView?.dataSource = self
        tableView?.delegate = self
        tableView?.cellLayoutMarginsFollowReadableWidth = false
        
        for value in previousSelectedValues {
            tableView?.selectRow(at: IndexPath(row: data.index(of: value)!, section: 0), animated: false, scrollPosition: .none)
        }
        
        if textField.text?.length == 0 {
//            setSelected(index:0)
        }
        
        let toolbar = UIToolbar()
        toolbar.barStyle = UIBarStyle.default
        toolbar.sizeToFit()
        
        let flexibleSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
        let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.plain, target: self, action: #selector(DownTableView.doneClick(sender:)))
        
        if shouldDisplayCancelButton {
            
            let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: #selector(DownTableView.cancelClicked(sender:)))
            
            toolbar.setItems([cancelButton, flexibleSpace, doneButton], animated: false)
            
        } else {
            toolbar.setItems([flexibleSpace, doneButton], animated: false)
        }
        
        textField.inputView = tableView
        textField.inputAccessoryView = toolbar
    }
    
    // UITextFieldDelegate
    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
        return true
    }
    
    func textFieldDidBeginEditing(_ textField: UITextField) {
        if data.count > 0 {
            showTableView(sender: textField)
        }
    }
    
    func textFieldDidEndEditing(_ textField: UITextField) {
        textField.isUserInteractionEnabled = true
    }
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        return false
    }
    
    // UITableViewDataSource
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        var cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
        
        if cell == nil {
            cell = DownTableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "Cell")
        }
        
        let item = data[indexPath.row]
        
        cell?.textLabel?.text = item.name
        
        return cell!
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 44
    }
    
    // UITableViewDelegate
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        selectedValues.append(data[indexPath.row])
        
        textField.text = toString(productsAttributes: selectedValues)
    }
    
    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        
        let element = data[indexPath.row]
        
        if let index = selectedValues.index(of: element) {
            selectedValues.remove(at: index)
        }
        
        textField.text = toString(productsAttributes: selectedValues)
    }
    
    private func toString(productsAttributes list:[ProductAttribute]) -> String {
        
        var selectedValuesStrings = [String]()
        
        for value in selectedValues {
            selectedValuesStrings.append(value.name!)
        }
        
        return selectedValuesStrings.joined(separator: ",")
    }
    
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        
        if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
            cell.separatorInset = UIEdgeInsets.zero
        }
        if cell.responds(to: #selector(setter: UIView.preservesSuperviewLayoutMargins)) {
            cell.preservesSuperviewLayoutMargins = false
        }
        if cell.responds(to: #selector(setter: UIView.layoutMargins)) {
            cell.layoutMargins = UIEdgeInsets.zero
        }
    }
}

lunes, 26 de diciembre de 2016

iOS: Upload to AppStore

1) Organizer

2) Application Loader

Choose Xcode > Open Developer Tool > Application Loader from the menu bar.

You need to generate the ipa for App Store distribution.