how to enable button when button already changed in swift - swift

so i have 3 buttons.
the first one for take a picture/pick image from gallery
the second one for take an autograph and segue it to another view controller
the last one is the next button
i want to disable my next button if the user have not full fill the image and the signature.And enable the button if user already full fill the image and the signature

Probably not the best solution but this should work:
button3.isEnabled = false
var signature: String = "" {
didSet {
button3.isEnabled = (image != nil && signature != "")
}
}
var image: UIImage? {
didSet {
button3.isEnabled = (image != nil && signature != "")
}
}

Related

SwiftUI Prevent user from tapping button while entering data

If the user clicks the button while editing the TextField (cursor flashing) in DataPtView, the app crashes.
In a list cell, I have the button, which impacts the view that is also shown in the cell.
Here's a snippet, iPad specific.
CellView:
VStack{
Button("TagOut"){
self.tagOut.toggle()
}
if self.tagOut {
TagOutView(question: question)
}
if !self.tagOut{
if question.type == "Y/N"{
YesOrNoView(question: question)
} else if question.type == "DataPt"{
DataPtView(question: question)
} else {
RecordEntryView()
}
...
DataPtView:
...
TextField("Data: ", text: $collectedData)
.onReceive(Just(collectedData)) {value in
let filtered = value.filter {"01234567890-".contains($0)}
if filtered != value{
self.invalidCollectedData = true
} else {
self.invalidCollectedData = false
}
}
...
I'm also using an AdaptsToKeyboard ViewModifier for when CellView is covered by the keyboard.
move-textfield-up-when-the-keyboard-has-appeared-in-swiftu
How do I prevent this from happening? If user hides the keyboard before clicking the button, everything is fine, but that isn't intuitive.
What if you try to check if your modifier height is greater than 0 and based on this handle the button click. In your cell view define:
#State var keyboardHeight: CGFloat = 0
Change your AdaptsToKeyboardModifier to have binding var inside it:
struct AdaptsToKeyboard: ViewModifier {
#Binding var currentHeight: CGFloat = 0
...
}
Now you need to initialize your modifier with the following constructor:
.modifier(AdaptsToKeyboard(currentHeight: $keyboardHeight))
Now you have two options to handle the button press:
To disable the button interaction:
Button("TagOut"){
self.tagOut.toggle()
}.disabled(keyboardHeight > 0)
To ignore the press:
Button("TagOut") {
if self.keyboardHeight == 0 {
self.tagOut.toggle()
}
}

PDFAnnotation Radiobutton don't change background color or don't display value

I use PDFKit in iOS as PDF renderer and I have problem with background color in radio button.
I iterate all PDF annotations on all pages in the document.
override func viewDidAppear(_ animated: Bool) {
//let pdfData = ... received data from file storage ...
if let document = PDFDocument(data: pdfData) {
for i in 0...document.pageCount {
if let page = document.page(at: i) {
for annot in page.annotations {
if annot.widgetControlType == .radioButtonControl {
annot.backgroundColor = UIColor.red
}
}
}
}
}
}
When I set the background color, nothing happens.
But when I try to set the background color to the type of Text annotation, the color changes.
The difference between the Radio button and the Text annotation is in its type.
The Radio button has a widgetFieldType == .button and the Text has a widgetFieldType == .text.
I think this is the reason why it doesn't work.
Next I try to remove annotation, change his background color and add again. This also doesn't work.
if annot.widgetControlType == .radioButtonControl {
page.removeAnnotation(annot)
annot.backgroundColor = UIColor.red
page.addAnnotation(annot)
}
But when I create a new instance of PDFAnnotaion, and I add it to the page, it works.
if annot.widgetControlType == .radioButtonControl {
page.removeAnnotation(annot)
let newAnnot = PDFAnnotation(bounds: annot.bounds, forType: .widget, withProperties: nil)
newAnnot.backgroundColor = UIColor.red
newAnnot.widgetStringValue = annot.widgetStringValue
page.addAnnotation(newAnnot)
}
The big problem is that the value of this Radio button is not displayed, even though it contains the value itself.
If in another method I get all the values from PDF annotations, there is also the right value from this radio button.
The Radio button contains the value, only it is displayed.
I tried to copy all the properties PDF annotation from the annot to newAnnot, but it didn't help.
How to properly change the background color of the Radio button and display its value?

Can I put a static image in a UIButton.imageView? that is animating?

I have a custom UIButton (MovesButton) with an image that I don't want to change or remove. But when I set button.imageView?.animationImages with bunch of images and start animating it, it removes my button's initial photo I have. If I have the static photo as a background, it looks like it is on fire. I want the fire to be as a background and preferably in the same UIButton class.
private func putAnimation(button: MovesButton) {
var images: [UIImage] = []
if button.animation == ButtonAnimations.None {
print("None11")
return
} else if button.animation == ButtonAnimations.SmallFire {
for i in 0 ... ButtonAnimations.SmallFire.1 {
images.append(UIImage(named: "\(ButtonAnimations.SmallFire.0)\(i)")!) //ButtonAnimations.SmallFire.0 = "smallFire"
}
} else if button.animation == ButtonAnimations.BigFire {
for i in 0 ... ButtonAnimations.BigFire.1 {
images.append(UIImage(named: "\(ButtonAnimations.BigFire.0)\(i)")!)
}
} else { print("weird button animations") }
button.imageView?.animationImages = images
button.imageView?.animationDuration = 1
button.imageView?.startAnimating()
}
I don't want to use a hacky trick of putting an imageView or another button behind MovesButton
I want the same animation result as a button.imageView.animationImages but as the backgroundImage. Is this possible?
Instead of image view animation, use image animation. Call UIImage animatedImage(with:duration:) to form an animated image. Set that as your button’s background image and you’re all set.

How can I UITest the change of the image of a UIButton in Swift?

When I tap a UIButton, the image should change to reflect its new state (e.g. Record -> Pause etc).
In my XCode UITest function, how do I interrogate the buttons current image after the tap to assert that its image has changed correctly to the correct image's .png file?
I did it like this
// Find the button by the image name
// In this example the image's names are "record_image" and "pause_image"
// "_" are replaced by " " in the image name when searching
let recordButton = XCUIApplication().buttons["record image"]
recordButton.tap()
XCTAssertFalse(recordButton.exists) // Record button won't exist anymore since the image has changed
let pauseButton = XCUIApplication().buttons["pause image"]
XCTAssertTrue(pauseButton.exists)
pauseButton.tap()
XCTAssertFalse(pauseButton.exists)
XCTAssertTrue(recordButton.exists)
I did like this, not best way but efficient for me,
every image change I changed accessibility identifier then checked the access.ids
public func setFollowed(_ isFollowed: Bool) {
if isFollowed {
followButton.setImage(UIImage(named: "followed-green-icon"), for: .normal)
followButton.accessibilityIdentifier = "ProfileInfoView_followButton_followed"
}
else {
followButton.setImage(UIImage(named: "follow-blue-icon"), for: .normal)
followButton.accessibilityIdentifier = "ProfileInfoView_followButton_follow"
}
}
sample UI test part:
func getFollowButton(isFollowed: Bool) -> XCUIElement {
if isFollowed == true {
return app.descendants(matching: .button)["ProfileInfoView_followButton_followed"]
} else {
return app.descendants(matching: .button)["ProfileInfoView_followButton_follow"]
}
}
then tested returned element, state changed etc.

Binding textfield text to enable button not working

I am new to reactive programming, and Bond framework specifically. I know I may be doing things that are wrong in my basic understanding of this programming technique. This is the situation:
I have a UITextView and an "approve" UIButton.
I want the approve button to be enabled only when the text in the textView is not nil. I have tried adding these lines of code into my viewDidLoad method in my ViewController.
textView.reactive.text.observeNext{(text) in
self.message = text
print(text)
}
textView.reactive.text.map { $0 != nil}.bind(to: approveButtonOutlet.reactive.isEnabled)
The first action works (printing the text is happening successfully on every input change).
The second one does not work, the button is enabled both when the text is not nil and when it is.
Any help appreciated.
You can try like
RAC(self.approveButtonOutlet, enabled) = [self.textView.rac_textSignal map:^id(NSString *text) {
return #(text.length > 0);
}];
I'm not sure how it will be in swift 3 just try like
RAC(self.approveButtonOutlet, enabled) = self.textView.rac_textSignal.map({(text: String) -> void in
return (text.length > 0)
})
I found the issue was that I had a placeholder in my textView, which prevented from the text really being nil. So what eventually I did is this:
textView.reactive.text.map {
if $0 == placeholder {
return false
} else if $0 != nil {
return $0!.characters.count > 0
} else{
return false
}
}.bind(to: approveButtonOutlet.reactive.isEnabled)