How to check for self with contains() in Swift?
If you look at the declaration of the viewControllers
property, you notice that it's [AnyObject]!
and not [UIViewController]!
.
The contains
function requires that the sequence element implements the Equatable
protocol, which AnyObject
doesn't.
The solution is to make an explicit downcast of that array, using optional binding:
if let viewControllers = self.navigationController?.viewControllers as? [UIViewController] {
if (contains(viewControllers, self)) {
println("Back button not pressed")
} else {
self.updateSearchQueryModel()
}
}
How do I check if a string contains another string in Swift?
You can do exactly the same call with Swift:
Swift 4 & Swift 5
In Swift 4 String is a collection of Character
values, it wasn't like this in Swift 2 and 3, so you can use this more concise code1:
let string = "hello Swift"
if string.contains("Swift") {
print("exists")
}
Swift 3.0+
var string = "hello Swift"
if string.range(of:"Swift") != nil {
print("exists")
}
// alternative: not case sensitive
if string.lowercased().range(of:"swift") != nil {
print("exists")
}
Older Swift
var string = "hello Swift"
if string.rangeOfString("Swift") != nil{
println("exists")
}
// alternative: not case sensitive
if string.lowercaseString.rangeOfString("swift") != nil {
println("exists")
}
I hope this is a helpful solution since some people, including me, encountered some strange problems by calling containsString()
.1
PS. Don't forget to import Foundation
Footnotes
- Just remember that using collection functions on Strings has some edge cases which can give you unexpected results, e. g. when dealing with emojis or other grapheme clusters like accented letters.
How to check if an element is in an array
Swift 2, 3, 4, 5:
let elements = [1, 2, 3, 4, 5]
if elements.contains(5) {
print("yes")
}
contains()
is a protocol extension method of SequenceType
(for sequences of Equatable
elements) and not a global method as in
earlier releases.
Remarks:
- This
contains()
method requires that the sequence elements
adopt theEquatable
protocol, compare e.g. Andrews's answer. - If the sequence elements are instances of a
NSObject
subclass
then you have to overrideisEqual:
, see NSObject subclass in Swift: hash vs hashValue, isEqual vs ==. - There is another – more general –
contains()
method which does not require the elements to be equatable and takes a predicate as an
argument, see e.g. Shorthand to test if an object exists in an array for Swift?.
Swift older versions:
let elements = [1,2,3,4,5]
if contains(elements, 5) {
println("yes")
}
Use contains() to check if back button pressed in Swift
Similar to RAJAMOHAN-S I look at where I'm transitioning from. However, the function
override func willMove(toParentViewController parent: UIViewController?)
provides a nice way of doing that; I combined with a simple bool variable to differentiate if the back button was really used or whether another programmatic method meant a transition event.
override func willMove(toParentViewController parent: UIViewController?) {
super.willMove(toParentViewController: parent)
if parent == nil {
// The back button was pressed, can be acted on
}
}
else{
print ("Coming here from a child view")
}
}
Check if subview exists in swift 1.2
Rather than asking if a subview exists in your view, you are better off asking if the subview (in your case noticeSubView) has a parent that is your view.
So in your example you would check later for:
if ( noticeSubView.superview === self.view ) {
...
}
The triple "===" is making sure that the superview object is the same object as self.view, instead of trying to call isEqual() on the view.
Another approach people have used in the past is to set an integer tag on a subview, like so:
noticeSubView.tag = 4
The default is zero so anything nonzero will be unique.
Then you can check to see if a superview contains a specific view by tag:
if ( self.view?.viewWithTag(4) != nil )
...
}
If you take that approach, you should probably create an enum for the integer value so it's clearer what you are looking for.
Note: There's a "?" after self.view
because a view controller will not have a view defined until after viewDidLoad
, the "?" makes sure the call will not occur if self.view
returns .None
How to check if a string contains an int? -Swift
You can use Foundation methods with Swift strings, and that's what you should do here. NSString
has built in methods that use NSCharacterSet
to check if certain types of characters are present. This translates nicely to Swift:
var str = "Hello, playground1"
let decimalCharacters = CharacterSet.decimalDigits
let decimalRange = str.rangeOfCharacter(from: decimalCharacters)
if decimalRange != nil {
print("Numbers found")
}
If you're interested in restricting what can be typed, you should implement UITextFieldDelegate
and the method textField(_:shouldChangeCharactersIn:replacementString:)
to prevent people from typing those characters in the first place.
How to check if a string only contains numbers in Swift 2?
In Swift 2 NSRegularExpression "throws" so you have to use it with try
.
Also you can't pass nil
for options anymore: if you don't want to specify options, pass an empty array (same for firstMatchInString
).
And self.length()
should become self.characters.count
.
Last note: if the goal is to determine if a String contains only numbers, and since you're naming it "isNumbersOnly", the resulting Boolean should be true if there's only numbers: it's currently the inverse. I've fixed this in my example.
Ignoring errors:
let regexNumbersOnly = try! NSRegularExpression(pattern: ".*[^0-9].*", options: [])
return regexNumbersOnly.firstMatchInString(self, options: [], range: NSMakeRange(0, self.characters.count)) == nil
With proper error handling:
do {
let regexNumbersOnly = try NSRegularExpression(pattern: ".*[^0-9].*", options: [])
return regexNumbersOnly.firstMatchInString(self, options: [], range: NSMakeRange(0, self.characters.count)) == nil
} catch let error as NSError {
print(error.description)
}
How to make sure that a string contains a whole word not just part of it
A possible way is to search with Regular Expression and the word boundary specifier \\b
if textFileStringContent.data.range(of: "\\b\(self.text)\\b", options: [.caseInsensitive, .regularExpression]) != nil {
Checking if an array of custom objects contain a specific custom object
There are two contains
functions:
extension SequenceType where Generator.Element : Equatable {
/// Return `true` iff `element` is in `self`.
@warn_unused_result
public func contains(element: Self.Generator.Element) -> Bool
}
extension SequenceType {
/// Return `true` iff an element in `self` satisfies `predicate`.
@warn_unused_result
public func contains(@noescape predicate: (Self.Generator.Element) throws -> Bool) rethrows -> Bool
}
The compiler is complaining because the compiler knows that Person
is not Equatable
and thus contains
needs to have a predicate
but alex
is not a predicate.
If the people in your array are Equatable
(they aren't) then you could use:
person.list.contains(alex)
Since they aren't equatable, you could use the second contains
function with:
person.list.contains { $0.name == alex.name }
or, as Martin R points out, based on 'identity' with:
person.list.contains { $0 === alex }
or you could make Person
be Equatable
(based on either name
or identity).
Related Topics
Macos Swift UI View Where There Is a Search Field in The Title Bar
Possible Bug? I Can Create Generic Instance Ignoring Constraint
Allow Line Editing When Reading Input from The Command Line
Swift Nstimer Dynamically Changing Interval
Swiftui List .Ondelete: Index Out of Range
How to Show an Alert in Swift UIalertview Not Working
Midiclientcreate Does Not Work for 32 Bit Processors in Swift
Cocos2D Fcm Push Notification Not Working
Where to Place Code for Audio Playback in a Swiftui App
How to Post Parameter with (+ Plus Sign) in Alamofire
How to Cut a Hole in a Sprite Image or Texture to Show What Is Behind It Using Spritekit in Swift
Wkwebview Problems in Macos Mojave
Mkpolyline Broken When Using Type Satelliteflyover
Can't Hide Status Bar in Avplayerviewcontroller's Portrait Mode
Data Structure for Fast Lookup with Multiple Criteria
Nstimer() - Timer.Invalidate Not Working on a Simple Stopwatch
Hit Fatal Error: Unexpectedly Found Nil While Unwrapping an Optional Value (Lldb)