Recently, I picked up the development of iOS again, and used OC and Swift to mix. I encountered some tricky problems, which are recorded here for the convenience of myself and others not to fall into the pit in the future. The contents of this article include:

  1. The actual structure of UITableViewCell
  2. Use regular expressions in iOS
  3. How to hide tabbar elegantly
  4. How to change the color of navigationBar
  5. Modify the view using Autolayout at run time
  6. Navigation Controller child view offset problem
  7. Summary of CoreData usage
  8. Resolve Git Xcode conflicts

1. The actual structure of UITableViewCell

The goal was to remove the Drag button from UITableview in Editing mode and replace it with its own style, but still want to preserve the native drag sorting behavior, so we explored a number of methods and finally found the structure of the UITableViewCell and replaced the drag button. Without further ado, go to the code.

// Po self > (LLDB) Po self.subviews 5 elements - [0] :; layer = > - [1] : <_UITableViewCellSeparatorView: 0x7d087c40; frame = (15 55; 1) 305; layer = > - [2] : <_UITableViewCellSeparatorView: 0x7b163240; Frame = (15, 55.5; 305, 0.5); layer = > - [3] : > - [4] : > (lldb) po self.subviews.last Optional - Some : > (lldb) po self.subviews.last? .subviews Optional> Some : 1 elements - [0] : > (lldb)Copy the code

Can see the contentView around all inward indent distance, finally has a view called UITableViewCellReorderControl, I think it is, and then look at its subviews, actually contains a UIImageView, decisive to replace it, Here’s the code.

override func layoutSubviews() { super.layoutSubviews() setupReorderControl() } func setupReorderControl() { if (self.reorderControl ! = nil) { return; } for view in self.subviews { if view.description.containsString("UITableViewCellReorderControl") { self.reorderControl = view } } if ((self.reorderControl) ! = nil) { let imageOfReorder = self.reorderControl? .subviews[0] as? UIImageView imageOfReorder? .removeFromSuperview() } }Copy the code

At this point, the ability to hide the drag button is complete, but notice that it is not successful to change the position of the reorderControl frame by setting it. I think its layout is autolayout without further investigation.

2. Use regular expressions in the iOS environment

Using regex on iOS can seem cumbersome, but if you just want to use regex to judge formatting, you can use NSPredicate:

let string = "abcd"
let predicate = NSPredicate.init(format: "self matches %@", "^a(b|c)d$")
predicate.evaluateWithObject(string)Copy the code

If you want to use the regular judgment format, and then get the group substring, it is more troublesome, there is no Swift native method to do this, must use NSRegularExpression, without further words, above code:

let reg = try! NSRegularExpression.init(pattern: "^a(b|c)d$", options: NSRegularExpressionOptions.CaseInsensitive) let matches = reg.matchesInString(string, options: NSMatchingOptions.init(rawValue: 0), range: NSMakeRange(0, string.characters.count)) if matches? .count > 0 { let returnString = (string as NSString).substringWithRange(matches! [0].rangeAtIndex(1)) }Copy the code

3. How to hide tabbar elegantly

Many apps use TabBarController with NavigationController as the application framework, so hiding TabBar becomes a necessary function. At present, the simplest method is to use hidden Bottom Barwhenpushed to achieve. The easiest way to do this is to override the default values by writing the following method in the Controller that hides the TAB bar.

- (BOOL) hidesBottomBarWhenPushed {
    return (self.navigationController.topViewController == self);
}Copy the code

4. How to change the color of navigationBar

[self.navigationController.navigationBar setTranslucent:NO]; self.navigationController.navigationBar.barTintColor = [UIColor redColor]; / / in this method to restore color - (void) viewWillDisappear: (BOOL) animated {self. NavigationController. NavigationBar. BarTintColor = [UIColor whiteColor]; [super viewWillDisappear:animated];Copy the code

}

5. Modify the view using Autolayout at run time

The solution is to add constraints to the view at runtime.

NSLayoutConstraint *c = [NSLayoutConstraint constraintWithItem:view1
                                                     attribute:NSLayoutAttributeTop
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem: view2
                                                     attribute: NSLayoutAttributeTop
                                                    multiplier:1
                                                      constant:2];Copy the code

View1 (top) = View2 (top) * 1 + 2 This code means to put the top of view1 two pixels down from the top of view2 (because at this point view1 is view2’s subview, So the effect is that view1 is 2 pixels down from the top of view2.) Here are all the attributes:

The left side of the NSLayoutAttributeLeft view and the right side of the NSLayoutAttributeRight view and the top side of the NSLayoutAttributeTop view and the bottom side of the NSLayoutAttributeBottom view NSLayoutAttributeLeading view of the front NSLayoutAttributeTrailing view behind the NSLayoutAttributeWidth NSLayoutAttributeHeight the width of the view The height of the view NSLayoutAttributeCenterX the halfway point of the view of the Y value of X value NSLayoutAttributeCenterY view point NSLayoutAttributeBaseline view datum No attribute NSLayoutAttributeNotAnAttributeCopy the code

6. Navigation Controller child view offset problem

The scenario looks like this: the page uses a UItableview layout, and because the page is complex, the first cell is offset downward as it is pushed in and out. Solution:

// Add to viewDidLoad:  if ([self respondsToSelector:@selector(edgesForExtendedLayout)]){ self.edgesForExtendedLayout = UIRectEdgeNone; }Copy the code

7. Summary of CoreData usage

// // coreDataHelper. swift // TestCode // // Created by LK on 16/7/6. // Copyright © 2016 LK. All rights reserved import Foundation import CoreData @objc class CoreDataHelper: NSObject { static let KEY_OF_MAX_ORDER_NUMBER_OF_I = "MIK" static let KEY_OF_MAX_ORDER_NUMBER_OF_O = "MOK" var context :  NSManagedObjectContext! static let sharedInstance = CoreDataHelper() private func fetchQuery(request request : NSFetchRequest) -> [NSManagedObject] { do{ let fetchResults = try context? .executeFetchRequest(request) as! [NSManagedObject]! Return fetchResults}catch let error as NSError {print(" query failed: \\(error)")} return []} private func save() -> Void {// save do{try context.save()} catch let error as NSError { Print (" save failed: \\(error)")}} //TODO: private func addIncrement(key _key: String, newNumber: Int) -> Void { if _key == CoreDataHelper. KEY_OF_MAX_ORDER_NUMBER_OF_O || _key == CoreDataHelper.KEY_OF_MAX_ORDER_NUMBER_OF_I { NSUserDefaults.standardUserDefaults().setInteger(newNumber, forKey: _key)}} / / Mark: - to calculate the maximum func recaculateOptionalMaxOrder () - > Void {let topOptinal = getOptionals (count: 1) if topOptinal.count > 0 { NSUserDefaults.standardUserDefaults().setInteger(topOptinal[0].order! KEY_OF_MAX_ORDER_NUMBER_OF_O)}} //MARK: - Add func addXXX(code code: String, name: String) -> Void {if (context == nil) {print(" Add failed, The context is nil ") return} let s = NSEntityDescription. InsertNewObjectForEntityForName (" s ", inManagedObjectContext: context) as! S // object assignment s.code = code s.name = name s.numericalcode = info.code s.type = info.type save()} Func removeAll() -> Void {let fetchRequest = NSFetchRequest(entityName: "S") let fetchResults = fetchQuery(request: FetchRequest) for info: nS-managed object in fetchResults {// Delete context.deleteObject(info)} save()} //MARK: - Query func getObject(code code: String) -> S? {if (context == nil) {print(" query failed, context = nil") return nil; } let fetchRequest = NSFetchRequest(entityName: "S") let predicate = NSPredicate(format: "code == %@ || numericalCode == %@", code, code) fetchRequest.predicate = predicate let fetchResults = fetchQuery(request: fetchRequest) if let ses = fetchResults as? [S] {if ses. Count > 0{return SES [0]}else{return nil}} return nil} //MARK: - Search func searchStocks(filterString: String) -> [Stock] { var attribute = "code"; let num = Int(filterString) if filterString.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) <= 0 { return [] } else if num == nil { //TODO attribute = "name" } let fetchRequest = NSFetchRequest(entityName: "S") fetchRequest.predicate = NSPredicate.init(format: "%K CONTAINS %@", attribute, filterString) let fetchResults = fetchQuery(request: FetchRequest) print(" result: ") print(fetchResults) var ses = [S]() for fetchResults {let S = res as! S ses.append(s) } return ses }Copy the code

8. Resolve Git Xcode conflicts

To be continued…