# -*- encoding : utf-8 -*- module ChaWork module Basic def main UIApplication.sharedApplication.delegate end def push(view, bool=true, hide=true) view.hidesBottomBarWhenPushed = hide self.navigationController.pushViewController(view, animated:bool) end def show(view, bool=true) # NOTE: -[UIViewController presentModalViewController] is deperated! self.presentViewController(view, animated:bool, completion: nil) # self.presentModalViewController(view, animated:true) end def hide(bool=true) self.dismissModalViewControllerAnimated(bool) end def pop(bool=true) self.navigationController.popViewControllerAnimated(bool) end def pop_to_root(bool=true) self.navigationController.popToRootViewControllerAnimated(bool) end # '0,0,0,0' = 'x,y,w,h', 若x为负数则表示向右对齐, 若为负数,则表示view.height - 数值 def get_frame(str) if str.nil? warn('frame为nil') return [[0,0],[0,0]] end return str if str.class == Array frame = str.split(',') x = get_value(frame[0]) y = get_value(frame[1]) width = get_value(frame[2]) height= get_value(frame[3]) [[x, y], [width, height]] end # 格式,100/80, /号前是4寸屏值,/号后是3.5寸屏值 def get_value(val) if val.nil? NSLog("frame error, missing") return 0 end array = val.split("/") # 若只有一个值,直接返回 return val.to_i if array.length == 1 return UIScreen.mainScreen.bounds.size.height > 480 ? array[0].to_i : array[1].to_i end alias _ get_frame def full_view(color='#FFFFFF', opacity=1) frame = [[0,0], [UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height]] view = UIView.alloc.initWithFrame(frame) view.backgroundColor = "#{color}".uicolor.colorWithAlphaComponent(opacity) view end def create_view(frame, color='#FFFFFF', opacity=1, shadow=false) frame = get_frame(frame) view = UIView.alloc.initWithFrame(frame) opacity = 1 if opacity.nil? view.backgroundColor = "#{color}".uicolor.colorWithAlphaComponent(opacity) if shadow #view.layer.masksToBounds = NO #view.layer.cornerRadius = 8 view.layer.shadowOffset = CGSizeMake(1, 2) view.layer.shadowRadius = 1 view.layer.shadowOpacity = 0.3 end view end def bottom_line(frame, color='#ECECEC') frame = get_frame(frame) new_frame = [[frame[0][0], frame[0][1] + frame[1][1] - 0.5], [frame[1][0], 0.5]] bg = create_view(new_frame, color, 1) bg.autoresizingMask = UIViewAutoresizingFlexibleTopMargin bg end def footer(color='#FFFFFF') view = UIView.alloc.init view.backgroundColor = color.uicolor view end def label(text, frame, size=16, bold=false, color='#000000', align=nil, background=nil, shadow=false, shadow_color='#CCCCCC') frame = get_frame(frame) lbl = UILabel.alloc.initWithFrame(frame) lbl.text = text.to_s if background.nil? lbl.backgroundColor = UIColor.clearColor else lbl.backgroundColor = "#{background}".uicolor end lbl.highlightedTextColor = :white.uicolor lbl.textColor = color.uicolor unless color.nil? font_size = size.nil? ? 16 : size lbl.font = bold ? UIFont.boldSystemFontOfSize(font_size) : UIFont.systemFontOfSize(font_size) case align when nil, :left, 'left' lbl.textAlignment = UITextAlignmentLeft when :right, 'right' lbl.textAlignment = UITextAlignmentRight when :center, 'center' lbl.textAlignment = UITextAlignmentCenter end if shadow shadow_color = '#CCCCCC' if shadow_color.nil? lbl.shadowColor = shadow_color.uicolor lbl.shadowOffset = CGSizeMake(0, 1) end lbl end #自适应高度label def context(text, frame, font_size = 16, color='#000000', absolute=false, align=nil, length=nil) frame = get_frame(frame) color ||= '#000000' font_size ||= 16 lbl = UILabel.new lbl.backgroundColor = UIColor.clearColor lbl.textColor = color.uicolor font = UIFont.systemFontOfSize(font_size) width = frame[1][0] if absolute lbl.frame = frame else lbl.frame = CGRectMake(frame[0][0], frame[0][1], width, text.height(width: width, size: font_size)) end case align when nil, :left, 'left' then lbl.textAlignment = NSTextAlignmentLeft when :right, 'right' then lbl.textAlignment = NSTextAlignmentRight when :center, 'center' then lbl.textAlignment = NSTextAlignmentCenter end lbl.font = font lbl.numberOfLines = 0 lbl.lineBreakMode = NSLineBreakByWordWrapping lbl.text = text lbl end def button(text, frame, size=16, color='#1D92B5', action=nil, param=nil, align=nil, bold=false) size ||= 16 color ||= '#1D92B5' frame = get_frame(frame) button = UIButton.alloc.initWithFrame(frame) button.titleLabel.font = bold ? UIFont.boldSystemFontOfSize(size) : UIFont.systemFontOfSize(size) button.setTitle(text, forState:UIControlStateNormal) button.setTitleColor(color.uicolor, forState:UIControlStateNormal) # button.setTitleColor(:darkgray.uicolor, forState:UIControlStateHighlighted) case align when nil, :center, 'center' button.setContentHorizontalAlignment(UIControlContentHorizontalAlignmentCenter) when :right, 'right' button.setContentHorizontalAlignment(UIControlContentHorizontalAlignmentRight) when :left, 'left' button.setContentHorizontalAlignment(UIControlContentHorizontalAlignmentLeft) end case action when 'back' then button.on(:touch) { pop } when 'hide' then button.on(:touch) { hide } when 'user' then button.on(:touch) { push UserDetail.alloc.initWithId(param) } # TODO: Decouple UserDetail else unless action.nil? if param.nil? button.on(:touch) { send(action) } else button.on(:touch) { send(action, param) } end end end button end def bbutton(text, frame, type=:info, action=nil) frame = get_frame(frame) symbol = {info: BButtonTypeInfo, success: BButtonTypeSuccess, danger: BButtonTypeDanger, default: BButtonTypeDefault, primary: BButtonTypePrimary, warning: BButtonTypeWarning} type = symbol[type] || BButtonTypeInfo btn = BButton.alloc.initWithFrame(frame, type:type, style:BButtonStyleBootstrapV3) btn.setTitle(text, forState:UIControlStateNormal) btn.on(:touch) { send(action) } if action btn end def change_btn_image(btn, name) btn.setImage(name.uiimage, forState:UIControlStateNormal) end def image_btn(name, frame, action=nil, param=nil) frame = get_frame(frame) button = UIButton.alloc.initWithFrame frame if name.include? ',' val = name.split(",") button.setImage(val[0].uiimage, forState:UIControlStateNormal) button.setImage(val[1].uiimage, forState:UIControlStateHighlighted) else button.setImage(name.uiimage, forState:UIControlStateNormal) end case action when 'back' then button.on(:touch) { pop } when 'hide' then button.on(:touch) { hide } else unless action.nil? if param.nil? button.on(:touch) { send(action) } else button.on(:touch) { send(action, param, button) } end end end button end def image(url, frame, placeholder='photo', round=false, fit=false) placeholder ||= 'photo' frame = get_frame(frame) image_view = UIImageView.alloc.initWithFrame frame if url.nil? || url == '' image_view.image = placeholder.uiimage elsif url.class == UIImage image_view.image = url elsif url.downcase.include? 'http' image_view.setImageWithURL(url.nsurl, placehoderImage:placeholder.uiimage) if fit image_view.contentMode = UIViewContentModeScaleAspectFill image_view.clipsToBounds = true # image_view.setImageWithURL(url.nsurl, # success:-> image, cached do # ratio = image.size.width / 320 # height= 200 #frame[1][1] # rect = [[0, 0], [image.size.width, height * ratio]] # imageRef = CGImageCreateWithImageInRect(image.CGImage, rect) # img = UIImage.imageWithCGImage imageRef # CGImageRelease(imageRef) # image_view.image = img # end, failure:nil) end # warn("1:#{url}") elsif url.class == String image_view.image = url.uiimage else image_view.image = placeholder.uiimage end if round image_view.layer.cornerRadius = frame[1][1] / 2 image_view.layer.masksToBounds = true end image_view end def update_image(image_view, url, placeholder='photo') return if url.nil? || url == '' if url.class == UIImage image_view.image = url elsif url.downcase.include? 'http' image_view.setImageWithURL(url.nsurl, placehoderImage:placeholder.uiimage) elsif url.class == String image_view.image = url.uiimage end image_view end def map(location ,frame, span=0.1, type='standard', show_me=false) map_view = MKMapView.alloc.initWithFrame(frame) map_view.mapType = (type == 'satellite') ? MKMapTypeSatellite : MKMapTypeStandard # 显示用户当前的坐标 map_view.showsUserLocation=true if show_me region = MKCoordinateRegion.new region.center.latitude = location[0] region.center.longitude = location[1] span = 0.1 if span.nil? region.span.latitudeDelta = span region.span.longitudeDelta = span map_view.region = region map_view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight map_view end def custom_item(view) UIBarButtonItem.alloc.initWithCustomView(view) end def bar_item(title, action_name) item = UIBarButtonItem.alloc.initWithTitle(title, style:UIBarButtonItemStyleBordered, target:self, action:action_name) item end def image_item(image_name, action_name) UIBarButtonItem.alloc.initWithImage(image_name.uiimage, style: UIBarButtonItemStyleBordered, target: self, action: action_name) end def action_item(action_name) item = UIBarButtonItem.alloc. initWithBarButtonSystemItem(UIBarButtonSystemItemAction, target:self, action:action_name) item end def system_item(symbol, action_name) name = { done: UIBarButtonSystemItemDone, cancel: UIBarButtonSystemItemCancel, edit: UIBarButtonSystemItemEdit, save: UIBarButtonSystemItemSave, add: UIBarButtonSystemItemAdd, flexible_space: UIBarButtonSystemItemFlexibleSpace, fixed_space: UIBarButtonSystemItemFixedSpace, compose: UIBarButtonSystemItemCompose, reply: UIBarButtonSystemItemReply, action: UIBarButtonSystemItemAction, organize: UIBarButtonSystemItemOrganize, bookmarks: UIBarButtonSystemItemBookmarks, search: UIBarButtonSystemItemSearch, refresh: UIBarButtonSystemItemRefresh, stop: UIBarButtonSystemItemStop, camera: UIBarButtonSystemItemCamera, trash: UIBarButtonSystemItemTrash, play: UIBarButtonSystemItemPlay, pause: UIBarButtonSystemItemPause, rewind: UIBarButtonSystemItemRewind, fast_forward: UIBarButtonSystemItemFastForward, undo: UIBarButtonSystemItemUndo, redo: UIBarButtonSystemItemRedo, page_curl: UIBarButtonSystemItemPageCurl }[symbol] || UIBarButtonSystemItemDone item = UIBarButtonItem.alloc. initWithBarButtonSystemItem(name, target:self, action:action_name) item end # 系统add按扭 def add_item(action_name) item = UIBarButtonItem.alloc. initWithBarButtonSystemItem(UIBarButtonSystemItemAdd, target:self, action:action_name) item end # 系统refresh按扭 def refresh_item(action_name) item = UIBarButtonItem.alloc. initWithBarButtonSystemItem(UIBarButtonSystemItemRefresh, target:self, action:action_name) item end def textfield(frame, placeholder='', text='', is_secure=false) frame = get_frame(frame) field = UITextField.alloc.initWithFrame(frame) field.placeholder = placeholder.to_s field.secureTextEntry = is_secure field.borderStyle = UITextBorderStyleNone # UITextBorderStyleRoundedRect field.returnKeyType = UIReturnKeyNext field.delegate = self field.text = text.to_s field end def textview(args={}) frame = get_frame(args[:frame]) tv = UITextView.alloc.initWithFrame(frame) tv.font = UIFont.systemFontOfSize(args[:font_size]) if args[:font_size] tv.layer.cornerRadius = args[:radius] if args[:radius] tv.delegate = self tv end def password_field(frame, placeholder='', text='') textfield(frame, placeholder.to_s, text.to_s, true) end def add_subviews(view, objs) objs.each { |obj| view.addSubview(obj) if !obj.nil? } view end def set_image(btn, name) btn.setImage(name.uiimage, forState:UIControlStateNormal) btn end # 生成segement def segment(frame, items, actions, default=0, color='#FF9900') items = items.split(",") actions = actions.split(",") #初始化UISegmentedControl segmentedControl = UISegmentedControl.alloc.initWithItems(items) segmentedControl.frame = get_frame(frame) segmentedControl.selectedSegmentIndex = default segmentedControl.tintColor = color.uicolor segmentedControl.segmentedControlStyle = UISegmentedControlStylePlain segmentedControl.on(:value_changed) do if actions.length >= segmentedControl.selectedSegmentIndex + 1 action = actions[segmentedControl.selectedSegmentIndex] send(action) end end segmentedControl end def friendly_time(from_time, include_seconds = false) if from_time.class == Bignum time_value = from_time - Time.now.to_i else time_value = from_time - Time.now end distance_in_minutes = (((time_value).abs)/60).round distance_in_seconds = ((time_value).abs).round case distance_in_minutes when 0..1 return (distance_in_minutes == 0) ? '不到1分钟' : '1分钟' unless include_seconds case distance_in_seconds when 0..4 then '刚刚' when 5..9 then '10秒前' when 10..19 then '20秒前' when 20..39 then '半分钟前' when 40..59 then '不到1分钟' else '1分钟' end when 2..44 then "#{distance_in_minutes}分钟前" when 45..89 then '1小时前' when 90..1439 then "#{(distance_in_minutes.to_f / 60.0).round} 小时前" when 1440..2879 then '1天前' when 2880..43199 then "#{(distance_in_minutes / 1440).round}天前" when 43200..86399 then '1个月前' when 86400..525599 then "#{(distance_in_minutes / 43200).round}个月" when 525600..1051199 then '1年左右' else "#{(distance_in_minutes / 525600).round}年" end end def log(msg) NSLog(msg) end def empty_cell cell = UITableViewCell.alloc.init cell.contentView.subviews.each do |subview| subview.removeFromSuperview end cell end def loading_view(height=nil) height = height || self.view.frame.size.height bg = create_view("0,0,320,#{height}", '#FFFFFF', 0) progressInd = UIActivityIndicatorView.alloc.initWithActivityIndicatorStyle(UIActivityIndicatorViewStyleGray) bg.addSubview progressInd progressInd.center= [110, height/2] progressInd.startAnimating bg.addSubview label('请稍后...', [[130, height/2-7], [100,16]], 16, false, '#878787') bg end def open_url(url) unless url.is_a?(NSURL) url = NSURL.URLWithString(url) end UIApplication.sharedApplication.openURL(url) end # Displays a UIAlertView. # # title - The title as a String. # args - The title of the cancel button as a String, or a Hash of options. # (Default: { cancel_button_title: 'OK' }) # cancel_button_title - The title of the cancel button as a String. # message - The main message as a String. # block - Yields the alert object if a block is given, and does so before the alert is shown. # # Returns an instance of BW::UIAlertView def alert(title, args={}) alert = UIAlertView.alloc.initWithTitle(title, message:'', delegate:self, cancelButtonTitle:"确定", otherButtonTitles:nil) alert.show alert end end end