UISearchBar search icon isnot left aligned in iOS7 - iphone

In iOS7 the search icon and place holder text are always appearing in middle.I tried changing the text alignment of the text field in search bar to left but it didn't work.
Is there any way to make the searchbar search icon appear left aligned in iOS7
I tried the following lines but it did not work:
UITextField *txfSearchField = [_searchBar valueForKey:#"_searchField"];
txfSearchField.textAlignment = NSTextAlignmentLeft;
[_searchArticle setImage:image forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];
UIimageView *im = [UIImageView alloc]init];
im.image = image;
txfSearchField.leftView =im;

There is no way to change the alignment of search bar's placeholder text, I tried so many "SO" answer but no one was working. Finally I ended with this workaround
Give some white space in right of placeholder text
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
// Load resources for iOS 6.1 or earlier
self.searchBar.placeholder = #"hello";
} else {
// Load resources for iOS 7 or later
self.searchBar.placeholder = #"hello ";
}
Enjoy !!

In Swift-3 :-
Magnify icon can be Left alignment by adding the subview over searchBar and nullify default Magnify icon.
let width = 20
let height = 20
func changeSearchBarIcon() {
let topView: UIView = searchBar.subviews[0] as UIView
var searchField:UITextField!
for subView in topView.subviews {
if subView is UITextField {
searchField = subView as! UITextField
break
}
}
if ((searchField) != nil) {
let leftview = searchField.leftView as! UIImageView
let magnifyimage = leftview.image
let imageView = UIImageView(frame: CGRect(x: searchBar.frame.origin.x , y: 10, width: width, height: height ) )
imageView.image = magnifyimage
searchField.leftView = UIView(frame: CGRect(x: 0 , y: 0, width: width, height: height) )
searchField.leftViewMode = .always
searchField.superview?.addSubview(imageView)
}
}

This is not a good solution but it works. (Test on iOS 9)
import UIKit
class MySearchBar: UISearchBar {
override func layoutSubviews() {
super.layoutSubviews()
if let l = getTextFieldLabel() {
l.addObserver(self, forKeyPath: "frame", options: .New, context: nil)
}
if let i = getIcon() {
i.addObserver(self, forKeyPath: "frame", options: .New, context: nil)
}
}
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if let l = object as? UILabel {
l.removeObserver(self, forKeyPath: "frame")
l.frame = CGRect(x: 29, y: 1, width: 323, height: 25)
l.addObserver(self, forKeyPath: "frame", options: .New, context: nil)
}
if let i = object as? UIImageView {
i.removeObserver(self, forKeyPath: "frame")
i.frame = CGRect(x: 8, y: 7.5, width: 13, height: 13)
i.addObserver(self, forKeyPath: "frame", options: .New, context: nil)
}
}
func getTextFieldLabel() -> UILabel? {
for v in self.allSubViews(self) {
if NSStringFromClass(v.dynamicType) == "UISearchBarTextFieldLabel" {
return v as? UILabel
}
}
return nil
}
func getIcon() -> UIImageView? {
for v in self.allSubViews(self) {
if NSStringFromClass(v.dynamicType) == "UIImageView" {
return v as? UIImageView
}
}
return nil
}
func allSubViews( v : UIView!) -> [UIView] {
var views : [UIView] = []
views += v.subviews
for s in v.subviews {
views += allSubViews(s)
}
return views
}
}

1 subclass a uitextField
2 in initWithFrame
[self setBackgroundColor:[UIColor clearColor]];
[self setTextAlignment:NSTextAlignmentLeft];
[self setContentVerticalAlignment:UIControlContentVerticalAlignmentCenter];
[self setAutocorrectionType:UITextAutocorrectionTypeNo];
[self setAutocapitalizationType:UITextAutocapitalizationTypeNone];
[self setPlaceholder:#"Search"];
[self setLeftView:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"search-icon"]]];
[self setLeftViewMode:UITextFieldViewModeAlways];
3 in main class include UItextfieldDelegate and implement following delegate method
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString* searchString = [textField.text stringByReplacingCharactersInRange:range withString:string];
searchYourFriendsArray = [[NSMutableArray alloc] init];
if(searchString.length > 0 )
{
NSMutableArray *searchArray = [NSMutableArray arrayWithArray:yourFriendsArray];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"FirstName beginswith[C] %# OR LastName beginswith[C] %#",searchString,searchString];
searchYourFriendsArray = [NSMutableArray arrayWithArray:[searchArray filteredArrayUsingPredicate:predicate]];
}
return YES;
}

Workaround for iOS 9:
extension ViewController: UISearchBarDelegate {
func searchBarShouldBeginEditing(searchBar: UISearchBar) -> Bool {
if let searchTextField = searchBar.valueForKey("_searchField") as? UITextField {
if let placeholderLabel = searchTextField.valueForKey("_placeholderLabel") as? UILabel {
if searchTextField.textColor == placeholderLabel.textColor {
searchTextField.text = ""
searchTextField.textColor = UIColor.blackColor()
searchTextField.clearButtonMode = .Always
}
}
}
return true
}
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
if searchBar.text == "" {
if let searchTextField = searchBar.valueForKey("_searchField") as? UITextField {
if let placeholderLabel = searchTextField.valueForKey("_placeholderLabel") as? UILabel {
searchBar.text = "Placeholder"
searchTextField.textColor = placeholderLabel.textColor
searchTextField.clearButtonMode = .Never
}
}
}
searchBar.resignFirstResponder()
}
}

You can call this method, and it looks like screenshot:
+(void)customizeDisplayForSeachbar:(UISearchBar *)searchBar
{
searchBar.barTintColor = [UIColor whiteColor];
searchBar.layer.borderWidth = 0.0;
searchBar.layer.borderColor = [UIColor clearColor].CGColor;
UITextField *txfSearchField = [searchBar valueForKey:#"_searchField"];
UIImage *imageIcon=[UIImage imageNamed:#"search_icon.png"];
float iconWidth=14;
UIImageView *imgView=[[UIImageView alloc] initWithFrame:CGRectMake(15, (txfSearchField.superview.frame.size.height-iconWidth)/2-1, iconWidth, iconWidth)];
imgView.contentMode=UIViewContentModeScaleAspectFit;
imgView.image=imageIcon;
txfSearchField.leftView=[[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 40)];
txfSearchField.leftViewMode=UITextFieldViewModeAlways;
[txfSearchField.superview addSubview:imgView];
}

Related

Unable to Display Name Caption Label for Various Images in Carousel View

I have a carousel view to my view controller to display images. I am trying to set a name label for each image which appears while scrolling through the Carousel View. But, when I use the following if/else statement to set the nameLabel field it is not changing with different images on the carousel view. Can anyone please let me know what is the problem ion my code? Appreciate your help!
func carousel(_ carousel: iCarousel, viewForItemAt index: Int, reusing view: UIView?) -> UIView {
let view = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width/1.4, height: 300))
view.backgroundColor = .red
let imageview = UIImageView(frame: view.bounds)
view.addSubview(imageview)
imageview.contentMode = .scaleToFill
imageview.image = UIImage(named: "Image_\(index+1)")
if (imageview.image == UIImage(named: "Image_1")) {
NameLabel.text = "Cat"
}
if (imageview.image == UIImage(named: "Image_2")) {
NameLabel.text = "Dog"
}
if (imageview.image == UIImage(named: "Image_3")) {
NameLabel.text = "Rat"
}
if (imageview.image == UIImage(named: "Image_4")) {
NameLabel.text = "Tiger"
}
if (imageview.image == UIImage(named: "Image_5")) {
NameLabel.text = "Leopard"
}
if (imageview.image == UIImage(named: "Image_6")) {
NameLabel.text = "Squirrel"
}
return view
}

Search bar with corner radius in swift

I want to create a view like the above image.it has a search bar with corner radius.but when i am trying to create, i am unable to make the search bar with corner radius.also i am unable to make the text field of the search bar with corner radius. i have writtenall my code in viewDidAppear method. It is ok or i have to write it in viewWillLayourSubview. so that i will be able to make the exact
same search bar like this image. also i want the seach icon to be placed slightly right.
My code is:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
for subView in searchBar.subviews {
for subsubView in subView.subviews {
if let textField = subsubView as? UITextField {
var bounds: CGRect
var placeHolder = NSMutableAttributedString()
let Name = "Search"
placeHolder = NSMutableAttributedString(string:Name, attributes: [NSAttributedString.Key.font:UIFont(name: "Helvetica", size: 15.0)!])
placeHolder.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.gray, range:NSRange(location:0,length:Name.count))
textField.attributedPlaceholder = placeHolder
if let leftView = textField.leftView as? UIImageView {
leftView.image = leftView.image?.withRenderingMode(.alwaysTemplate)
leftView.frame.size.width = 15.0
leftView.frame.size.height = 15.0
leftView.tintColor = UIColor.gray
}
textField.layer.cornerRadius = 50.0
bounds = textField.frame
bounds.size.width = searchBar.frame.width
bounds.size.height = searchBar.frame.height
textField.bounds = bounds
textField.borderStyle = UITextField.BorderStyle.roundedRect
searchBar.backgroundImage = UIImage()
textField.backgroundColor = UIColor.lightGray.withAlphaComponent(0.2)
searchBar.searchTextPositionAdjustment = UIOffset(horizontal: 5, vertical: 0)
}
}
}
}*
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
for subView in searchBar.subviews {
if !subView.subviews.contains(where: { $0 as? UITextField != nil }) { continue }
guard let textField = subView.subviews.first(where: { $0 as? UITextField != nil }) as? UITextField else { return }
let placeholder = NSMutableAttributedString(
string: "Search",
attributes: [.font: UIFont(name: "Helvetica", size: 15.0)!,
.foregroundColor: UIColor.gray
])
textField.attributedPlaceholder = placeholder
textField.borderStyle = UITextField.BorderStyle.roundedRect
textField.layer.cornerRadius = textField.frame.size.height / 2
textField.layer.masksToBounds = true
textField.textColor = .white
textField.backgroundColor = .lightGray
}
searchBar.barTintColor = .white
searchBar.backgroundColor = .white
searchBar.searchTextPositionAdjustment = UIOffset(horizontal: 5, vertical: 0)
}
Doesn't look exactly like in the image that you linked, but actually fits better into the Apple design and works better than the code that you wrote.
For anything more sophisticated, I would advise to create a custom UISearchBar subclass.
Be aware of Apple's Human Interface Guidelines, so anything too crazy / different from default might not be accepted in the AppStore.

Segmented control is only working on first press

I want to give the option to change the background of my app.
Everything is working fine when I want to change the background colour only. But I have to use a background image.
I am using the code below for that
import UIKit
class ContainerController: UIViewController {
var isRaindrops = false
var Background:String = "UIImage(named: \"Background\")"
override func viewDidLoad() {
super.viewDidLoad()
BackgroundSwitch()
self.view.backgroundColor = .white
}
func BackgroundSwitch() {
let items = ["Gradient", "Raindrops"]
let segmentedControl = UISegmentedControl(items: items)
segmentedControl.translatesAutoresizingMaskIntoConstraints = false
segmentedControl.frame = CGRect(x: 20, y: self.view.frame.height * 0.2 + 50, width: self.view.frame.width - 40, height: 40)
segmentedControl.selectedSegmentIndex = 0
segmentedControl.tintColor = UIColor.black
segmentedControl.addTarget(self, action: #selector(segmentedControlInAction(sender:)), for: UIControl.Event.valueChanged)
self.view.addSubview(segmentedControl)
}
#objc func segmentedControlInAction(sender:UISegmentedControl) {
let index = sender.selectedSegmentIndex
switch index {
case 0:
print("Gradient")
Background = "Background"
print(Background)
// self.view.backgroundColor = .red
BackgroundSetup()
case 1:
(print("Raindrops"))
Background = "Raindrops"
print(Background)
// self.view.backgroundColor = .blue
BackgroundSetup()
default:
print("default")
break
}
}
func BackgroundSetup() {
let backgroundImage = UIImageView(frame: UIScreen.main.bounds)
backgroundImage.image = UIImage(named: Background)
self.view.insertSubview(backgroundImage, at: 0)
// self.view.backgroundColor = Background
}
}
With the code that I have at the moment, the background is only changing when I hit the "Raindrops" field for the first time.
I have a segmented tableview which I use both case switch and if like below.
if sender.selectedSegmentIndex == 0
{
print("Gradient")
Background = "Background"
print(Background)
BackgroundSetup()
}
if sender.selectedSegmentIndex == 1
{
(print("Raindrops"))
Background = "Raindrops"
print(Background)
BackgroundSetup()
}

Swift - how to apply resize images inside scrollview

I have a following scrollview code
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var pageControl: UIPageControl!
var imageArray = [UIImage(named: "mainScrollView1"), UIImage(named: "mainScrollView2"), UIImage(named: "mainScrollView3"),]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
configurePageControl()
scrollView.pagingEnabled = true
scrollView.showsHorizontalScrollIndicator = false
scrollView.delegate = self
for var i = 0; i < imageArray.count; i++ {
if i == 0 {
var imageView = UIImageView(frame: CGRectMake(0, 0, scrollView.frame.size.width, 160))
imageView.image = imageArray[i]
scrollView.addSubview(imageView)
} else {
var float: CGFloat = CGFloat(i)
var imageView = UIImageView(frame: CGRectMake(scrollView.frame.size.width * float, 0, scrollView.frame.size.width, 160))
imageView.image = imageArray[i]
scrollView.addSubview(imageView)
}
}
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width*3, scrollView.frame.size.height)
}
func configurePageControl() {
self.pageControl.numberOfPages = 3
self.pageControl.currentPage = 0
self.pageControl.tintColor = UIColor.redColor()
self.pageControl.pageIndicatorTintColor = UIColor.blackColor()
self.pageControl.currentPageIndicatorTintColor = UIColor.whiteColor()
self.view.addSubview(pageControl)
}
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
pageControl.currentPage = Int(pageNumber)
}
}
the problem is that images inside scroll a static ones, they do not change their size for different screen sizes and because of that it looks like this
as you see first image do not expands to fill whole screen width and because of this part of second image can be seen
How can this be fixed ?
You should update the image size after the view layout all subviews. You should do that in viewDidLayoutSubviews.
Something like this:
var imageArray = [UIImage(named: "mainScrollView1"), UIImage(named: "mainScrollView2"), UIImage(named: "mainScrollView3"),]
var imageViews:[UIImageView] = []
override func viewDidLoad() {
super.viewDidLoad()
configurePageControl()
scrollView.pagingEnabled = true
scrollView.showsHorizontalScrollIndicator = false
scrollView.delegate = self
for image in imageArray {
var imageView = UIImageView(image: image)
scrollView.addSubview(imageView)
imageViews.append(imageView)
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
for (index,imageView) in imageViews.enumerate() {
imageView.frame = CGRectMake(CGFloat(index)*scrollView.frame.size.width, 0, scrollView.frame.size.width, 160)
}
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width*3, scrollView.frame.size.height)
}

Adding Activity Indicator to UIAlertView

I'm trying to add UIActivityIndicatorView to UIAlertView but couldn't get it done. I have seen posts on this implementation and found out that it works only for versions below iOS7.
Below is the code I've tried...
var alert: UIAlertView = UIAlertView(title: "Title", message: "Please wait...", delegate: nil, cancelButtonTitle: "Cancel");
var loadingIndicator: UIActivityIndicatorView = UIActivityIndicatorView(frame: CGRectMake(0.0, 0.0, 10.0, 10.0)) as UIActivityIndicatorView
loadingIndicator.center = self.view.center;
loadingIndicator.hidesWhenStopped = true
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray
loadingIndicator.startAnimating();
alert.addSubview(loadingIndicator);
alert.show();
Is there anything specific thing to do for iOS7 and above to get this done?
try this code!!
var alert: UIAlertView = UIAlertView(title: "Title", message: "Please wait...", delegate: nil, cancelButtonTitle: "Cancel")
var loadingIndicator: UIActivityIndicatorView = UIActivityIndicatorView(frame: CGRect(x: 50, y: 10, width: 37, height: 37)) as UIActivityIndicatorView
loadingIndicator.center = self.view.center
loadingIndicator.hidesWhenStopped = true
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray
loadingIndicator.startAnimating();
alert.setValue(loadingIndicator, forKey: "accessoryView")
loadingIndicator.startAnimating()
alert.show();
I hope I helped you
For swift 4
Create an alert controller extension
extension UIAlertController {
private struct ActivityIndicatorData {
static var activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
}
func addActivityIndicator() {
let vc = UIViewController()
vc.preferredContentSize = CGSize(width: 40,height: 40)
ActivityIndicatorData.activityIndicator.color = UIColor.blue
ActivityIndicatorData.activityIndicator.startAnimating()
vc.view.addSubview(ActivityIndicatorData.activityIndicator)
self.setValue(vc, forKey: "contentViewController")
}
func dismissActivityIndicator() {
ActivityIndicatorData.activityIndicator.stopAnimating()
self.dismiss(animated: false)
}
}
Create Var a ctivityIndicatorAlert in your view controller and write display and dismiss methods in view controller like below
var activityIndicatorAlert: UIAlertController?
func displayActivityIndicatorAlert() {
activityIndicatorAlert = UIAlertController(title: NSLocalizedString("Loading", comment: ""), message: NSLocalizedString("PleaseWait", comment: "") + "...", preferredStyle: UIAlertController.Style.alert)
activityIndicatorAlert!.addActivityIndicator()
var topController:UIViewController = UIApplication.shared.keyWindow!.rootViewController!
while ((topController.presentedViewController) != nil) {
topController = topController.presentedViewController!
}
topController.present(activityIndicatorAlert!, animated:true, completion:nil)
}
func dismissActivityIndicatorAlert() {
activityIndicatorAlert!.dismissActivityIndicator()
activityIndicatorAlert = nil
}
You can also add UIViewcontroller extension For globally available above all methods.
extension UIViewController {
private struct activityAlert {
static var activityIndicatorAlert: UIAlertController?
}
//completion : ((Int, String) -> Void)?)
func displayIPActivityAlert(_ onCancel : (()-> Void)?) {
activityAlert.activityIndicatorAlert = UIAlertController(title: NSLocalizedString("Loading...", comment: ""), message: nil , preferredStyle: UIAlertController.Style.alert)
activityAlert.activityIndicatorAlert!.addActivityIndicator()
var topController:UIViewController = UIApplication.shared.keyWindow!.rootViewController!
while ((topController.presentedViewController) != nil) {
topController = topController.presentedViewController!
}
activityAlert.activityIndicatorAlert!.addAction(UIAlertAction.init(title:NSLocalizedString("Cancel", comment: ""), style: .default, handler: { (UIAlertAction) in
self.dismissIPActivityAlert()
onCancel?()
}))
topController.present(activityAlert.activityIndicatorAlert!, animated:true, completion:nil)
}
func dismissIPActivityAlert() {
activityAlert.activityIndicatorAlert!.dismissActivityIndicator()
activityAlert.activityIndicatorAlert = nil
}
}
For those using Objective-C. My solution wraps the UIActivityIndicatorView with a bigger view so the margin to the edge of UIAlertView is not so small.
#import "UIAlertView+ActivityIndicator.h"
#implementation UIAlertView (ActivityIndicator)
+ (UIAlertView *)alertViewWithActivityIndicator:(NSString *)title delegate:(id<UIAlertViewDelegate>)delegate;
{
UIAlertView *a = [[UIAlertView alloc] initWithTitle:title
message:nil
delegate:delegate
cancelButtonTitle:nil
otherButtonTitles:nil];
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
UIActivityIndicatorView *aiv = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
aiv.translatesAutoresizingMaskIntoConstraints = NO;
[v addSubview:aiv];
[v addConstraint:[NSLayoutConstraint constraintWithItem:aiv
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:v
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0]];
[v addConstraint:[NSLayoutConstraint constraintWithItem:aiv
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:v
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0]];
[aiv startAnimating];
[a setValue:v forKey:#"accessoryView"];
return a;
}
#end
The accepted answer in Swift 3:
var alert: UIAlertView = UIAlertView(title: "Title", message: "Please wait...", delegate: nil, cancelButtonTitle: "Cancel");
let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x:50, y:10, width:37, height:37))
loadingIndicator.center = self.view.center;
loadingIndicator.hidesWhenStopped = true
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
loadingIndicator.startAnimating();
alert.setValue(loadingIndicator, forKey: "accessoryView")
loadingIndicator.startAnimating()
alert.show();