diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index 7792cc046..fab3da656 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -184,6 +184,9 @@ 51D5948722668EFA00DFC836 /* MarkStatusCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84702AA31FA27AC0006B8943 /* MarkStatusCommand.swift */; }; 51D6A5BC23199C85001C27D8 /* MasterTimelineDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51D6A5BB23199C85001C27D8 /* MasterTimelineDataSource.swift */; }; 51D87EE12311D34700E63F03 /* ActivityType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51D87EE02311D34700E63F03 /* ActivityType.swift */; }; + 51E149B3234D82E40004F7A5 /* PasswordField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E149B2234D82E40004F7A5 /* PasswordField.swift */; }; + 51E149C0234D839E0004F7A5 /* ShowHidePasswordView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 51E149BF234D839E0004F7A5 /* ShowHidePasswordView.xib */; }; + 51E149C2234D852F0004F7A5 /* ShowHidePasswordView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E149C1234D852F0004F7A5 /* ShowHidePasswordView.swift */; }; 51E3EB33229AB02C00645299 /* ErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E3EB32229AB02C00645299 /* ErrorHandler.swift */; }; 51E3EB3D229AB08300645299 /* ErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E3EB3C229AB08300645299 /* ErrorHandler.swift */; }; 51E595A5228CC36500FCC42B /* ArticleStatusSyncTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E595A4228CC36500FCC42B /* ArticleStatusSyncTimer.swift */; }; @@ -802,6 +805,9 @@ 51CC9B3D231720B2000E842F /* MasterFeedDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterFeedDataSource.swift; sourceTree = ""; }; 51D6A5BB23199C85001C27D8 /* MasterTimelineDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterTimelineDataSource.swift; sourceTree = ""; }; 51D87EE02311D34700E63F03 /* ActivityType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityType.swift; sourceTree = ""; }; + 51E149B2234D82E40004F7A5 /* PasswordField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordField.swift; sourceTree = ""; }; + 51E149BF234D839E0004F7A5 /* ShowHidePasswordView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ShowHidePasswordView.xib; sourceTree = ""; }; + 51E149C1234D852F0004F7A5 /* ShowHidePasswordView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowHidePasswordView.swift; sourceTree = ""; }; 51E3EB32229AB02C00645299 /* ErrorHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorHandler.swift; sourceTree = ""; }; 51E3EB3C229AB08300645299 /* ErrorHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorHandler.swift; sourceTree = ""; }; 51E595A4228CC36500FCC42B /* ArticleStatusSyncTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleStatusSyncTimer.swift; sourceTree = ""; }; @@ -1244,6 +1250,9 @@ DF999FF622B5AEFA0064B687 /* SafariView.swift */, 51322858232FDDB80033D4ED /* VibrantButtonStyle.swift */, 51322854232EED360033D4ED /* VibrantSelectAction.swift */, + 51E149B2234D82E40004F7A5 /* PasswordField.swift */, + 51E149C1234D852F0004F7A5 /* ShowHidePasswordView.swift */, + 51E149BF234D839E0004F7A5 /* ShowHidePasswordView.xib */, ); path = "SwiftUI Extensions"; sourceTree = ""; @@ -2481,6 +2490,7 @@ 51F85BED227251DF00C787DC /* Acknowledgments.rtf in Resources */, 511D43D1231FA62800FB1562 /* SidebarKeyboardShortcuts.plist in Resources */, 51C452AB22650DC600C03939 /* template.html in Resources */, + 51E149C0234D839E0004F7A5 /* ShowHidePasswordView.xib in Resources */, 51F85BF12272524100C787DC /* Credits.rtf in Resources */, 84A3EE61223B667F00557320 /* DefaultFeeds.opml in Resources */, 511D43CF231FA62200FB1562 /* DetailKeyboardShortcuts.plist in Resources */, @@ -2709,6 +2719,7 @@ buildActionMask = 2147483647; files = ( 840D617F2029031C009BC708 /* AppDelegate.swift in Sources */, + 51E149B3234D82E40004F7A5 /* PasswordField.swift in Sources */, 512E08E72268801200BDCFDD /* FeedTreeControllerDelegate.swift in Sources */, 51C452A422650A2D00C03939 /* ArticleUtilities.swift in Sources */, 51EF0F79227716380050506E /* ColorHash.swift in Sources */, @@ -2777,6 +2788,7 @@ 51C4529A22650A0400C03939 /* ArticleStyle.swift in Sources */, 51C4527F2265092C00C03939 /* ArticleViewController.swift in Sources */, 51C4526A226508F600C03939 /* MasterFeedTableViewCellLayout.swift in Sources */, + 51E149C2234D852F0004F7A5 /* ShowHidePasswordView.swift in Sources */, 51C452AE2265104D00C03939 /* TimelineStringFormatter.swift in Sources */, 512E08E62268800D00BDCFDD /* FolderTreeControllerDelegate.swift in Sources */, 51C4529922650A0000C03939 /* ArticleStylesManager.swift in Sources */, diff --git a/iOS/Settings/Account/SettingsFeedbinAccountView.swift b/iOS/Settings/Account/SettingsFeedbinAccountView.swift index 511318a81..a685a8ada 100644 --- a/iOS/Settings/Account/SettingsFeedbinAccountView.swift +++ b/iOS/Settings/Account/SettingsFeedbinAccountView.swift @@ -31,7 +31,7 @@ struct SettingsFeedbinAccountView : View { TextField("Email", text: $viewModel.email) .keyboardType(.emailAddress) .textContentType(.emailAddress) - SecureField("Password", text: $viewModel.password) + PasswordField(password: $viewModel.password) } Section(footer: HStack { diff --git a/iOS/SwiftUI Extensions/PasswordField.swift b/iOS/SwiftUI Extensions/PasswordField.swift new file mode 100644 index 000000000..8875837ae --- /dev/null +++ b/iOS/SwiftUI Extensions/PasswordField.swift @@ -0,0 +1,25 @@ +// +// PasswordField.swift +// NetNewsWire-iOS +// +// Created by Maurice Parker on 10/8/19. +// Copyright © 2019 Ranchero Software. All rights reserved. +// + +import SwiftUI + +struct PasswordField: UIViewRepresentable { + + let password: Binding + + func makeUIView(context: Context) -> ShowHidePasswordView { + let showHideView = Bundle.main.loadNibNamed("ShowHidePasswordView", owner: Self.self, options: nil)?[0] as! ShowHidePasswordView + showHideView.passwordTextField.bindingString = password + return showHideView + } + + func updateUIView(_ showHideView: ShowHidePasswordView, context: Context) { + showHideView.passwordTextField.bindingString = password + } + +} diff --git a/iOS/SwiftUI Extensions/ShowHidePasswordView.swift b/iOS/SwiftUI Extensions/ShowHidePasswordView.swift new file mode 100644 index 000000000..fe6b10d02 --- /dev/null +++ b/iOS/SwiftUI Extensions/ShowHidePasswordView.swift @@ -0,0 +1,51 @@ +// +// ShowHidePasswordView.swift +// NetNewsWire-iOS +// +// Created by Maurice Parker on 10/8/19. +// Copyright © 2019 Ranchero Software. All rights reserved. +// + +import UIKit +import SwiftUI + +class ShowHidePasswordView: UIView { + + @IBOutlet weak var passwordTextField: BindingTextField! + @IBOutlet weak var showHideButton: UIButton! + + @IBAction func toggleShowHideButton(_ sender: Any) { + if passwordTextField.isSecureTextEntry { + passwordTextField.isSecureTextEntry = false + showHideButton.setTitle(NSLocalizedString("Hide", comment: "Hide"), for: .normal) + } else { + passwordTextField.isSecureTextEntry = true + showHideButton.setTitle(NSLocalizedString("Show", comment: "Show"), for: .normal) + } + } + +} + +class BindingTextField: UITextField, UITextFieldDelegate { + + var bindingString: Binding? = nil + + override init(frame: CGRect) { + super.init(frame: frame) + delegate = self + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + delegate = self + } + + func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + if let currentValue = textField.text as NSString? { + let proposedValue = currentValue.replacingCharacters(in: range, with: string) + bindingString?.wrappedValue = proposedValue + } + return true + } + +} diff --git a/iOS/SwiftUI Extensions/ShowHidePasswordView.xib b/iOS/SwiftUI Extensions/ShowHidePasswordView.xib new file mode 100644 index 000000000..d68686200 --- /dev/null +++ b/iOS/SwiftUI Extensions/ShowHidePasswordView.xib @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +