0%

直接设置titleLabel的text是无效的

extension UIButton {
///设置iconfont 但设置字体必须同时设置字体大小
/// - parameter str:iconfont 字串 如\u{e603}
/// - parameter fontSize:字体大小
func icon(str:String,fontSize: CGFloat) {

    self.titleLabel?.font = UIFont(name: "iconfont", size: fontSize)
    //swift使用unicode码
    self.setTitle(str, forState: UIControlState.Normal)
    
}

}

在plist里设置或者UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent 只能改变LaunchScreen的StatusBar,一旦进入ViewController,就会变成默认的黑色。 如果需要在显示viewController时,改变StatusBar前景色,需要override UIViewController的 preferredStatusBarStyle方法:

override func preferredStatusBarStyle() -> UIStatusBarStyle {
    return UIStatusBarStyle.LightContent
}

iOS7以后,默认支持右滑返回上一页,但是,当隐藏navigationBar或是自定义返回按钮时,右滑返回就会失效。解决方法,自己实现interactivePopGestureRecognizer的delegate viewDidLoad:

navigationController?.interactivePopGestureRecognizer!.delegate = self ;

实现UIGestureRecognizerDelegate定义的方法:

func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
    if (navigationController?.viewControllers.count <= 1 ) {
        return false;
    }
    return true;
}

cell有多行但只显示一行,报错 Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell’s content view. We’re considering the collapse unintentional and using standard height instead.显然是iOS认为我的cell没有高度,搜索了好多文章,基本上都是用

- (CGFloat)tableView:(UITableView *)tableView
estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 44;
}

- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 44;
}

给cell设置高度,但我每个cell的高度都不是固定的,需要动态计算,既然已经用了AutoLayout,感觉实现起来很渣。 偶然发现原因竟然是没有给最下面的view设置与superview的margin,iOS这个设计就有点傻,superview的高度在没有约束的时候,就不会自动根据content算。加上以后,两个问题解决。动态cell高度,需要加上

    tableView.estimatedRowHeight = 110
    tableView.rowHeight = UITableViewAutomaticDimension

预估的高度与实际接近就行

UISearchController一般用在搜索功能,通常的交互是在ViewController1上有个SearchBar,不可输入,点击searchBar,展示ViewController2,此时searchBar变成可编辑状态,输入keywork,在ViewController2里展示搜索提示,searchBar上有Cancel按钮,点击后返回ViewController1。很常见的交互,某些PD偷懒,不考虑Android的特性,让Android版本也实现同样的效果,虽然技术上也能实现,但是,这是iOS的特性,iOS自带控件,对一名有情怀的Android开发来说,就是摧残,包括精神和肉体… 代码来自极客学院视频教程,图书管理项目。虽然我是新手,但感觉老师某些地方代码还是有点问题,擅自改动了一些些,另外,要吐槽一下,作为年费VIP,我提的问题快超过24小时了没有任何答复…

显示搜索提示的SearchViewController:

import UIKit

class SearchViewController: UIViewController,UISearchResultsUpdating, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var tableView: UITableView!
weak var homeController: HomeViewController!

var searchController: UISearchController!

var searchTitles = \[String\]()
var books = \[Book\]()
override func awakeFromNib() {
    searchController = UISearchController(searchResultsController: self)
    searchController.searchResultsUpdater = self
    //hint
    searchController.searchBar.placeholder = "搜索图书"
    //光标和取消按钮的颜色
    searchController.searchBar.tintColor = UIColor.whiteColor()
    //删除默认灰色背景
    searchController.searchBar.subviews\[0\].subviews\[0\].removeFromSuperview()
}

func updateSearchResultsForSearchController(searchController: UISearchController) {
    //获取输入的关键字,过滤空白后,调接口
    if let tag = searchController.searchBar.text?.stringByTrimmingCharactersInSet(.whitespaceAndNewlineCharacterSet()) where !tag.isEmpty {
        HomeDataHandler.searchBook(tag, start: 0) { (books) -> Void in
            //接口返回,显示
            self.books = books!
            self.tableView.reloadData()
        }
    }
}

override func viewDidLoad() {
    tableView.dataSource = self
    tableView.delegate = self
    
}

//MARK: - UITableView -
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return books.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell = tableView.dequeueReusableCellWithIdentifier("searchCell")
    let book = books\[indexPath.row\]
    if cell == nil {
        cell = UITableViewCell()
    }
    cell?.textLabel?.text = book.title
    return cell!
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    var book = books\[indexPath.row\]
    searchController.active = false
}

}

界面很简单,就一个UITableView,但是得在顶上留点位置给searchBar,默认是44

要调用的ViewController里,顶部给SearchBar留Container View,下面的例子里叫searchView:

override func viewDidLoad() {
    super.viewDidLoad()
   
    let searchViewController = storyboard?.instantiateViewControllerWithIdentifier("searchController") as! SearchViewController
    searchViewController.homeController = self
    //把searchBar加上
    searchView.addSubview(searchViewController.searchController.searchBar)
    
}

封装了个HttpManager,通过AFNetworking处理http请求,AFNetworking 3.0已经废弃POST和GET方法,因为SwiftyJSON可以直接将NSData作为参数,没有返回没有转换成String,String只用于debug输出,可注释掉,减少性能浪费。 HttpManager.swift:

import AFNetworking

class HttpManager {
let manager = AFHTTPSessionManager()
private static let httpManager: HttpManager = HttpManager()

static var sharedInstance:HttpManager {
    return httpManager
}
private init() {
    manager.responseSerializer = AFHTTPResponseSerializer()
    manager.responseSerializer.acceptableContentTypes?.insert("text/html")
    manager.requestSerializer.timeoutInterval = 10
}

/// Http Get方法,不带参数
/// \- parameter url: 请求的URL
/// \- parameter success: 成功后回调的闭包
/// \- parameter encoding: 编码,默认utf-8
func get(url: String,encoding:UInt = NSUTF8StringEncoding,success:((NSData) -> Void)?, failure: ((NSError) -> Void)?) {
    return get(url, encoding: encoding, params: nil, success: success, failure: failure)
}

/// Http Get方法
/// \- parameter url: 请求的URL
/// \- parameter success: 成功后回调的闭包
/// \- parameter encoding: 编码,默认utf-8
/// \- parameter params: 参数,拼到url后缀里
func get(url: String,encoding:UInt = NSUTF8StringEncoding,params: \[String: AnyObject\]?,success:((NSData) -> Void)?, failure: ((NSError) -> Void)?) {
    return request(url, method: "GET", encoding: encoding, params: params, success: success, failure: failure)
}

/// Http Post方法
/// \- parameter url: 请求的URL
/// \- parameter success: 成功后回调的闭包
/// \- parameter encoding: 编码,默认utf-8
/// \- parameter params: Post 参数
func post(url: String,encoding:UInt = NSUTF8StringEncoding,params: \[String: AnyObject\]?, success:((NSData) -> Void)?, failure: ((NSError) -> Void)?) {
    return request(url, method: "POST", encoding: encoding, params: params, success: success, failure: failure)
}

///发送请求
/// \- parameter url: 请求URL
/// \- parameter method: 请求方法
/// \- parameter encoding: 编码,默认utf-8
/// \- parameter params:参数,如果是get,会添加到url后缀
/// \- parameter success: 成功回调闭包
/// \- parameter failure: 失败回调
func request(url: String, method: String = "GET",encoding:UInt = NSUTF8StringEncoding,params: \[String: AnyObject\]?, success:((NSData) -> Void)?, failure: ((NSError) -> Void)?) {
    
    let paramStr = NSMutableString()
    for (key,value) in params! {
        paramStr.appendString("\\(key)=\\(value)&")
    }
    var requestUrl = url;
    if(method == "GET") {
        requestUrl = "\\(url)?\\(paramStr)"
    }

    let urlRequest=NSMutableURLRequest(URL: NSURL(string: requestUrl)!)
    urlRequest.HTTPMethod = method
    urlRequest.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "content-type")
    
    if method == "POST" {
        let bodyData = paramStr.stringByAddingPercentEscapesUsingEncoding(encoding)?.dataUsingEncoding(encoding)
        urlRequest.HTTPBody = bodyData
    }

    let task = manager.dataTaskWithRequest(urlRequest) { (response, responseObj, error) -> Void in
        if (error != nil) {
            failure!(error!)
            return
        }
        let responseData = responseObj as! NSData
        let responseStr = NSString(data: responseData, encoding: encoding)
        PLog.v(responseStr!)
        success!(responseData)
    }
    task.resume()
}

默认情况下,http协议因为安全问题被禁止使用,可以在Info.plist里配置打开。 在根节点下添加”App Transport Security Settings”,在App Transport Security Settings下添加”Allow Arbitrary Loads”,Value设为YES 如下图: iOS-http-security

某些站点必须爬墙才能访问,但在mac上设置的全局代理,对终端又不起作用,终端需要单独设置代理。 在终端中执行:

export http_proxy=socks5://127.0.0.1:1080
export https_proxy=socks5://127.0.0.1:1080

如果是http的代理:

export http_proxy=http://127.0.0.1:1080/
export https_proxy=http://127.0.0.1:1080/

如果需要开机自动设置,把上面的代码加到~/.bash_profile里

所有SDK是从http://lbsyun.baidu.com/sdk/download?selected=navifunctionwithtts页面一次下载的,不应该存在兼容性问题。 我的地图和导航都在同一个Activity里,使用Fragment展示,初始化导航(BaiduNaviManager.getInstance().init)在Activity的onCreate方法里执行,会在MapFragment展示前执行.问题来了,在某些机器上,MapFragment竟然显示网格或空白,而注释掉初始化导航代码后,一切正常。 在这里不得不吐槽一下百度的sdk,使用文档就一页,几乎等于没写。官方demo,我选了多个sdk,下载下来的是各个sdk独立的,定位,导航,地图都是不同的demo,打了个包而已,导航sdk demo,也没有释放资源,uninit,某些sdk竟然还不是最新的.现在遇到的这个问题显然是bug。 折腾了大半天,最后发现初始化导航动作必须在地图第一次展示后执行,问题解决。原先用的是1.0.0版本的导航,但在某些设备上会crash,为了解决这个问题不得不升级,后面不知道还有多少坑。

生成图片的操作比较耗时,虽然是View对象,但咱是直接把View对象转成图片,不涉及修改UI显示,可以异步处理。

contentLayout.setDrawingCacheEnabled(true);
contentLayout.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
contentLayout.layout(0, 0, contentLayout.getMeasuredWidth(),
contentLayout.getMeasuredHeight());
contentLayout.buildDrawingCache();
Bitmap bitmap= contentLayout.getDrawingCache();