12

Here is a screenshot of a UIAlertController. I was just playing around custom fonts and textfield properties but I was unable to accomplish the following:

  • clear background of the UITextField
  • no ugly border (black box) as shown below

enter image description here

As I dived more into the code and iOS runtime headers, I was able to modify border and background color but the above issue still remains as those properties belong to a container UITextView. Changing background to clearColor doesn't help.

Has anybody ever played around with this? Not sure if I would ever take my app into production with such ugly text fields.

EDIT (May 13, 15) The answer below by Rory McKinnel is tested for iOS 8 - 8.3 and works just fine. The result is below:

enter image description here

p0lAris
  • 4,750
  • 8
  • 45
  • 80

8 Answers8

20

Had some fun with this. The following seems to work. Obviously judging by what was required, it has no future proofing and is a patch away from not working.

I figured this out by walking the view hierarchy in the debugger, from which I noticed a UIVisualEffectView. Removing that seems to give you what you want along with setting the containing view to a clear background. Without removing the visual effect, a clear background shows what is behind the alert view itself for some reason.

UIAlertController *alertController = 
 [UIAlertController alertControllerWithTitle:@"Its Not Pretty!" 
                                     message:@"Some times things get ugly!"                          
                              preferredStyle:UIAlertControllerStyleAlert];

[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField){
    textField.text = @"Text: No border and clear 8^)";

 }];
[self presentViewController:alertController animated:TRUE completion:^{
}];

for (UIView* textfield in alertController.textfields) {
    UIView *container = textField.superview;
    UIView *effectView = container.superview.subviews[0];

    if (effectView && [effectView class] == [UIVisualEffectView class]){
        container.backgroundColor = [UIColor clearColor];
        [effectView removeFromSuperview];
    }
}
Matthew
  • 837
  • 7
  • 20
Rory McKinnel
  • 7,936
  • 2
  • 17
  • 28
  • 1
    Brilliant! That's true; it might just break in the next patch but that's how life is. Hard. This is exactly what I was looking for. I myself tinkered a lot here but never thought about removing the visual effect view from the view hierarchy. – p0lAris May 14 '15 at 01:38
  • Doesn't work with iOS9.1, textField.superview is NULL. – Matthew Oct 29 '15 at 03:23
  • @Matthew Shame, it was not expected to last the test of time though. Sure your code is right? a text with no superview would imply it is not in the UI? cOuld your text field be null? – Rory McKinnel Oct 30 '15 at 06:30
  • 1
    @RoryMcKinnel: the textField is not added yet to the superview at that time, so the superview is NULL. It does work after the completion of presentViewController, but the sudden disappearance of the black border looks glitchy. – Matthew Oct 30 '15 at 07:31
  • 2
    @Matthew Try doing it after you call presentViewController rather than in the completion. After the present call the views should at be in place. Hopefully that should work. – Rory McKinnel Oct 30 '15 at 07:46
6

here is the important part in swift:

for textfield: UIView in alertController.textfields {
   var container: UIView = textField.superview
   var effectView: UIView = container.superview.subviews[0]
   container.backgroundColor = UIColor.clearColor()
   effectView.removeFromSuperview()
}
Paul Lehn
  • 3,202
  • 1
  • 24
  • 29
3

Swift 3 clear version

alertController.textFields?.forEach {
    $0.superview?.backgroundColor = .clear
    $0.superview?.superview?.subviews[0].removeFromSuperview()
}
zombie
  • 5,069
  • 3
  • 25
  • 54
2

You can try this. As you need only clear color to textfield of your alertview. simply add lines of code after your alertview is created.

 UITextField *textField = [alertView textFieldAtIndex:0];
 textField.backgroundColor=[UIColor clearColor];
 textField.superview.backgroundColor=[UIColor clearColor];

EDIT for alertviewCoontroller you can add

[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
        textField.backgroundColor=[UIColor clearColor];
        textField.superview.backgroundColor=[UIColor clearColor];

    }];

Thanks, revert if any confusion.

Kalyani
  • 392
  • 2
  • 17
1

You can change the border and background color like this:

    let subview = alertController!.view.subviews.first! as UIView
    let alertContentView = subview.subviews.first! as UIView
    alertContentView.backgroundColor = UIColor.lightGrayColor()
    alertContentView.layer.cornerRadius = 10;
    alertContentView.layer.borderWidth = 2;
R Thomas
  • 445
  • 4
  • 4
1

Swift 2.0 version:

for textField in alert.textFields! {
    if let container = textField.superview, let effectView = container.superview?.subviews.first where effectView is UIVisualEffectView {
       container.backgroundColor = UIColor.clearColor()
       effectView.removeFromSuperview()
    }
}
Mark Bourke
  • 9,806
  • 7
  • 26
  • 30
1

To address the situation as discussed in @Rory McKinnel and @Matthew where the superview are NULL and address modifying presented view:

extension UIAlertController {
    override open func viewWillAppear(_ animated: Bool) {
       super.viewWillAppear(animated)
       self.textFields?.forEach {
           $0.superview?.backgroundColor = .color
           $0.superview?.superview?.subviews[0].removeFromSuperview()
       }
    }
}
Matt
  • 399
  • 3
  • 6
0

This is very hacky, so examine it well before using (tested on iOS 8.3):

UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"My Alert"
                                                               message:@"This is an alert."
                                                        preferredStyle:UIAlertControllerStyleAlert];

[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {

    textField.placeholder = @"This is my placeholder";
    textField.backgroundColor = [UIColor colorWithRed:246.0/255.0 green:246.0/255.0 blue:246.0/255.0 alpha:1.0]; // You can change it to whatever color you want
    [textField superview].backgroundColor = textField.backgroundColor;
    [[textField superview] superview].backgroundColor = [UIColor whiteColor];

}];
Asaf
  • 2,158
  • 2
  • 25
  • 40
  • This does not seem to work. I want a clear background, i.e. the background color should basically be `clearColor`. This doesn't seem to achieve that. – p0lAris May 13 '15 at 00:56
  • Just give it the color of the alert background and it will demonstrate. – Asaf May 13 '15 at 06:56
  • I am not sure that is the requirement here. I just want a textfield that is a clear background, not the background of the alert. – p0lAris May 13 '15 at 07:46