Customizing length of passwords (while adding passwords)

This commit is contained in:
Yishi Lin 2017-03-09 02:19:47 +08:00
parent d761dd1fc5
commit 07782bd662
6 changed files with 147 additions and 6 deletions

View file

@ -8,16 +8,19 @@
import UIKit
class AddPasswordTableViewController: UITableViewController {
class AddPasswordTableViewController: UITableViewController, FillPasswordTableViewCellDelegate {
let tableTitles = ["name", "password", "additions"]
let tableRowsInSection = [1, 2, 1]
var password: Password?
var passwordLengthCell: SliderTableViewCell?
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UINib(nibName: "TextFieldTableViewCell", bundle: nil), forCellReuseIdentifier: "textFieldCell")
tableView.register(UINib(nibName: "TextViewTableViewCell", bundle: nil), forCellReuseIdentifier: "textViewCell")
tableView.register(UINib(nibName: "FillPasswordTableViewCell", bundle: nil), forCellReuseIdentifier: "fillPasswordCell")
tableView.register(UINib(nibName: "SliderTableViewCell", bundle: nil), forCellReuseIdentifier: "passwordLengthCell")
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 48
@ -25,7 +28,7 @@ class AddPasswordTableViewController: UITableViewController {
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
return tableRowsInSection[section]
}
override func numberOfSections(in tableView: UITableView) -> Int {
@ -39,8 +42,16 @@ class AddPasswordTableViewController: UITableViewController {
cell.contentTextView.text = ""
return cell
case "password":
let cell = tableView.dequeueReusableCell(withIdentifier: "fillPasswordCell", for: indexPath) as! FillPasswordTableViewCell
return cell
switch indexPath.row {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: "fillPasswordCell", for: indexPath) as! FillPasswordTableViewCell
cell.delegate = self
return cell
default:
passwordLengthCell = (tableView.dequeueReusableCell(withIdentifier: "passwordLengthCell", for: indexPath) as! SliderTableViewCell)
passwordLengthCell!.reset(title: "Length", minimumValue: 1, maximumValue: Globals.passwordMaximumLength, defaultValue: Globals.passwordDefaultLength)
return passwordLengthCell!
}
default:
let cell = tableView.dequeueReusableCell(withIdentifier: "textFieldCell", for: indexPath) as! TextFieldTableViewCell
cell.contentTextField.placeholder = tableTitles[indexPath.section]
@ -78,4 +89,9 @@ class AddPasswordTableViewController: UITableViewController {
let index = tableTitles.index(of: name)!
return getCellAt(section: Int(index))
}
func generatePassword() -> String {
let length = passwordLengthCell?.roundedValue ?? Globals.passwordDefaultLength
return Utils.generatePassword(length: length)
}
}

View file

@ -24,6 +24,9 @@ class Globals {
static let red = UIColor(red:1.00, green:0.23, blue:0.19, alpha:1.0)
static let blue = UIColor(red:0.00, green:0.48, blue:1.00, alpha:1.0)
static let passwordMaximumLength = 64
static let passwordDefaultLength = 16
private init() { }
}

View file

@ -8,9 +8,15 @@
import UIKit
protocol FillPasswordTableViewCellDelegate {
func generatePassword() -> String
}
class FillPasswordTableViewCell: ContentTableViewCell {
@IBOutlet weak var contentTextField: UITextField!
var delegate: FillPasswordTableViewCellDelegate?
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
@ -23,7 +29,7 @@ class FillPasswordTableViewCell: ContentTableViewCell {
}
@IBAction func generatePassword(_ sender: UIButton) {
let plainPassword = Utils.generatePassword(length: 16)
let plainPassword = self.delegate?.generatePassword() ?? Utils.generatePassword(length: 16)
contentTextField.attributedText = Utils.attributedPassword(plainPassword: plainPassword)
Utils.copyToPasteboard(textToCopy: plainPassword)
}

View file

@ -0,0 +1,49 @@
//
// SliderTableViewCell.swift
// pass
//
// Created by Yishi Lin on 8/3/17.
// Copyright © 2017 Yishi Lin. All rights reserved.
//
import UIKit
class SliderTableViewCell: UITableViewCell {
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var valueLabel: UILabel!
@IBOutlet weak var slider: UISlider!
var roundedValue: Int {
get {
return Int(slider.value)
}
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
@IBAction func handleSliderValueChange(_ sender: UISlider) {
let roundedValue = round(sender.value)
sender.value = roundedValue
valueLabel.text = "\(Int(roundedValue))"
}
func reset(title: String, minimumValue: Int, maximumValue: Int, defaultValue: Int) {
titleLabel.text = title
slider.minimumValue = Float(minimumValue)
slider.maximumValue = Float(maximumValue)
slider.value = Float(defaultValue)
valueLabel.text = String(defaultValue)
}
}

View file

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="KGk-i7-Jjw" customClass="SliderTableViewCell" customModule="pass" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="MwT-Jl-hhE">
<rect key="frame" x="64" y="6" width="188" height="31"/>
<connections>
<action selector="handleSliderValueChange:" destination="KGk-i7-Jjw" eventType="valueChanged" id="WwM-ZE-yIB"/>
</connections>
</slider>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Value" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GJP-Fj-VZt" userLabel="Value">
<rect key="frame" x="265" y="12" width="42" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="t7T-HC-hUd" userLabel="Title">
<rect key="frame" x="15" y="12" width="34" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="MwT-Jl-hhE" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" constant="-1" id="EXs-Rc-hZh"/>
<constraint firstItem="GJP-Fj-VZt" firstAttribute="baseline" secondItem="t7T-HC-hUd" secondAttribute="baseline" id="LQd-r7-6WY"/>
<constraint firstAttribute="trailingMargin" secondItem="GJP-Fj-VZt" secondAttribute="trailing" constant="5" id="TRd-h9-tjr"/>
<constraint firstItem="t7T-HC-hUd" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leadingMargin" constant="7" id="ebT-dV-tLI" userLabel="Title.leading = leadingMargin + 30"/>
<constraint firstItem="t7T-HC-hUd" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" id="h8e-Ng-Wt8"/>
<constraint firstItem="GJP-Fj-VZt" firstAttribute="leading" secondItem="MwT-Jl-hhE" secondAttribute="trailing" constant="15" id="i5e-Zi-SB5"/>
<constraint firstItem="MwT-Jl-hhE" firstAttribute="leading" secondItem="t7T-HC-hUd" secondAttribute="trailing" constant="17" id="nXq-30-GPf"/>
<constraint firstItem="GJP-Fj-VZt" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" constant="4" id="q1Y-pT-W8h"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="slider" destination="MwT-Jl-hhE" id="OLd-VI-AhL"/>
<outlet property="titleLabel" destination="t7T-HC-hUd" id="tNt-9O-jXP"/>
<outlet property="valueLabel" destination="GJP-Fj-VZt" id="25S-be-MPC"/>
</connections>
</tableViewCell>
</objects>
</document>